Initial commit

This commit is contained in:
PProvost 2020-05-11 08:51:44 -06:00
commit e0f67c0550
414 changed files with 201572 additions and 0 deletions

40
.gitattributes vendored Normal file
View File

@ -0,0 +1,40 @@
.git* export-ignore
.hooks* export-ignore
# Custom attribute to mark sources as using our C code style.
[attr]our-c-style whitespace=tab-in-indent eol=lf format.clang-format-6.0
# Custom attribute to mark sources as generated.
# Do not perform whitespace checks. Do not format.
[attr]generated whitespace=-tab-in-indent,-indent-with-non-tab -format.clang-format-6.0
bootstrap eol=lf
configure eol=lf
*.[1-9] eol=lf
*.bash eol=lf
*.sh eol=lf
*.sh.in eol=lf
*.bat eol=crlf
*.bat.in eol=crlf
*.sln eol=crlf
*.vcproj eol=crlf
*.pfx -text
*.png -text
*.png.in -text
*.c our-c-style
*.cc our-c-style
*.cpp our-c-style
*.cu our-c-style
*.cxx our-c-style
*.h our-c-style
*.hh our-c-style
*.hpp our-c-style
*.hxx our-c-style
*.notcu our-c-style
*.cmake whitespace=tab-in-indent
*.rst whitespace=tab-in-indent conflict-marker-size=79
*.txt whitespace=tab-in-indent

14
.gitignore vendored Executable file
View File

@ -0,0 +1,14 @@
.vscode/
_deps/
build/
CMakeFiles/
CMakeScripts/
CMakeLists.txt.user
CMakeCache.txt
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake

49
CMakeLists.txt Executable file
View File

@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
# Set up the project
project(netx
VERSION 6.0.0
LANGUAGES C ASM
)
if(NOT DEFINED THREADX_ARCH)
message(FATAL_ERROR "Error: THREADX_ARCH not defined")
endif()
if(NOT DEFINED THREADX_TOOLCHAIN)
message(FATAL_ERROR "Error: THREADX_TOOLCHAIN not defined")
endif()
# Define our target library and an alias for consumers
add_library(${PROJECT_NAME})
add_library("azrtos::${PROJECT_NAME}" ALIAS ${PROJECT_NAME})
# Define any required dependencies between this library and others
target_link_libraries(${PROJECT_NAME} PUBLIC
"azrtos::threadx"
)
# A place for generated/copied include files (no need to change)
set(CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/custom_inc)
# Pick up the port specific stuff first
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ports/${THREADX_ARCH}/${THREADX_TOOLCHAIN})
# Then the common files
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common)
# If the user provided an override, copy it to the custom directory
if (NOT NX_USER_FILE)
message(STATUS "Using default nx_user.h file")
set(NX_USER_FILE ${CMAKE_CURRENT_LIST_DIR}/common/inc/nx_user_sample.h)
else()
message(STATUS "Using custom nx_user.h file from ${NX_USER_FILE}")
endif()
configure_file(${NX_USER_FILE} ${CUSTOM_INC_DIR}/nx_user.h COPYONLY)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CUSTOM_INC_DIR}
)
target_compile_definitions(${PROJECT_NAME} PUBLIC "NX_INCLUDE_USER_DEFINE_FILE" )

246
LICENSE.txt Normal file
View File

@ -0,0 +1,246 @@
MICROSOFT SOFTWARE LICENSE TERMS
MICROSOFT AZURE RTOS
Shape
These license terms are an agreement between you and Microsoft Corporation (or
one of its affiliates). They apply to the software named above and any Microsoft
services or software updates (except to the extent such services or updates are
accompanied by new or additional terms, in which case those different terms
apply prospectively and do not alter your or Microsofts rights relating to
pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU
HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.
INSTALLATION AND USE RIGHTS.
General. You may install and use the software and the included Microsoft
applications solely for internal development, testing and evaluation purposes.
Any distribution or production use requires a separate license as set forth in
Section 2.
Contributions. Microsoft welcomes contributions to this software. In the event
that you make a contribution to this software you will be required to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and
actually do, grant Microsoft the rights to use your contribution. For details,
visit https://cla.microsoft.com.
Included Microsoft Applications. The software includes other Microsoft
applications which are governed by the licenses embedded in or made available
with those applications.
Third Party Components. The software may include third party components with
separate legal notices or governed by other agreements, as may be described
within the software or in the ThirdPartyNotices file(s) accompanying the
software.
Competitive Benchmarking. If you are a direct competitor, and you access or use
the software for purposes of competitive benchmarking, analysis, or intelligence
gathering, you waive as against Microsoft, its subsidiaries, and its affiliated
companies (including prospectively) any competitive use, access, and
benchmarking test restrictions in the terms governing your software to the
extent your terms of use are, or purport to be, more restrictive than
Microsofts terms. If you do not waive any such purported restrictions in the
terms governing your software, you are not allowed to access or use this
software, and will not do so.
DISTRIBUTION AND PRODUCTION USE. If you have obtained and/or are developing on
microprocessor(s) and/or microcontroller(s) (“hardware”) listed in the file
named “LICENSED-HARDWARE.txt” included in the repository and/or distributed with
the software you have the following rights in and to the software solely when
used in combination with the hardware. In the event hardware is not listed in
the LICENSED-HARDWARE.txt file, you do not have the rights in this Section 2.
Distribution and Production Use Rights.
You may use the software in production (e.g. program the modified or unmodified
software to devices you own or control) and distribute (i.e. make available to
third parties) the modified or unmodified binary image produced from this code.
You may permit your device distributors or developers to copy and distribute the
binary image as programmed or to be programmed to your devices.
You may redistribute the unmodified or modified source to your device
distributors or developers. Modifications must be clearly marked. Any
redistribution in source code form must contain this license and any other
licenses that accompany the software.
Requirements. For any code you distribute, you must:
when distributed in binary form, except as embedded in a device, include with
such distribution the terms of this agreement;
when distributed in source code form to distributors or developers of your
devices, include with such distribution the terms of this agreement; and
indemnify, defend and hold harmless Microsoft from any claims, including
attorneys fees, related to the distribution or use of your devices, except to
the extent that any claim is based solely on the unmodified software.
Restrictions. You may not:
use or modify the software to create a competing real time operating system
software;
remove any copyright notices or licenses contained in the software;
use Microsofts trademarks or trade dress in your application in any way that
suggests your device or application comes from or is endorsed by Microsoft;
transfer individual components, specific libraries, classes, functions or code
fragments of the software separately for purposes unrelated to the software; or
use or distribute the software in any way that would subject the software or
Microsofts intellectual property or technology to any other license terms.
SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all
other rights. Unless applicable law gives you more rights despite this
limitation, you will not (and have no right to):
remove, minimize, block, or modify any notices of Microsoft or its suppliers in
the software;
use the software in any way that is against the law or to create or propagate
malware; or
share, publish, distribute, or lease the software (except as permitted in
Section 2 above), or provide the software as a stand-alone offering for others
to use.
DATA. This software may interact with other Microsoft products that collect data
that is transmitted to Microsoft. To learn more about how Microsoft processes
personal data we collect, please see the Microsoft Privacy Statement at
https://go.microsoft.com/fwlink/?LinkId=248681.
EXPORT RESTRICTIONS. You must comply with all domestic and international export
laws and regulations that apply to the software, which include restrictions on
destinations, end users, and end use. For further information on export
restrictions, visit https://aka.ms/exporting.
SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any
support services for the software. Any support provided is “as is”, “with all
faults”, and without warranty of any kind.
UPDATES. Microsoft may periodically update the software. You may obtain updates
only from Microsoft or Microsoft-authorized sources. Updates may not include or
support all existing software features, services, or peripheral devices.
TERMINATION. Without prejudice to any other rights, Microsoft may terminate this
agreement if you fail to comply with any of its terms or conditions. In such
event, you must destroy all copies of the software and all of its component
parts.
ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for
supplements, updates, or third-party applications, is the entire agreement for
the software. To the extent you have entered into a separate agreement with
Microsoft relating specifically to the software, the terms in such agreement
shall control.
APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in
the United States or Canada, the laws of the state or province where you live
(or, if a business, where your principal place of business is located) govern
the interpretation of this agreement, claims for its breach, and all other
claims (including consumer protection, unfair competition, and tort claims),
regardless of conflict of laws principles. If you acquired the software in any
other country, its laws apply. If U.S. federal jurisdiction exists, you and
Microsoft consent to exclusive jurisdiction and venue in the federal court in
King County, Washington for all disputes heard in court. If not, you and
Microsoft consent to exclusive jurisdiction and venue in the Superior Court of
King County, Washington for all disputes heard in court.
CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal
rights. You may have other rights, including consumer rights, under the laws of
your state or country. Separate and apart from your relationship with Microsoft,
you may also have rights with respect to the party from which you acquired the
software. This agreement does not change those other rights if the laws of your
state or country do not permit it to do so. For example, if you acquired the
software in one of the below regions, or mandatory country law applies, then the
following provisions apply to you:
Australia. You have statutory guarantees under the Australian Consumer Law and
nothing in this agreement is intended to affect those rights.
Germany and Austria.
i.Warranty. The properly licensed software will perform substantially as
described in any Microsoft materials that accompany the software. However,
Microsoft gives no contractual guarantee in relation to the licensed software.
ii.Limitation of Liability. In case of intentional conduct, gross negligence,
claims based on the Product Liability Act, as well as, in case of death or
personal or physical injury, Microsoft is liable according to the statutory law.
Subject to the foregoing clause ii., Microsoft will only be liable for slight
negligence if Microsoft is in breach of such material contractual obligations,
the fulfillment of which facilitate the due performance of this agreement, the
breach of which would endanger the purpose of this agreement and the compliance
with which a party may constantly trust in (so-called "cardinal obligations").
In other cases of slight negligence, Microsoft will not be liable for slight
negligence.
DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF
USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO
THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED
WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT.
LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING
DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM
MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT
RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL,
INDIRECT, OR INCIDENTAL DAMAGES.
This limitation applies to (a) anything related to the software, services,
content (including code) on third party Internet sites, or third party
applications; and (b) claims for breach of contract, warranty, guarantee, or
condition; strict liability, negligence, or other tort; or any other claim; in
each case to the extent permitted by applicable law.
It also applies even if Microsoft knew or should have known about the
possibility of the damages. The above limitation or exclusion may not apply to
you because your state, province, or country may not allow the exclusion or
limitation of incidental, consequential, or other damages.
Please note: As this software is distributed in Canada, some of the clauses in
this agreement are provided below in French.
Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce
contrat sont fournies ci-dessous en français.
EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel
». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft
naccorde aucune autre garantie expresse. Vous pouvez bénéficier de droits
additionnels en vertu du droit local sur la protection des consommateurs, que ce
contrat ne peut modifier. La ou elles sont permises par le droit locale, les
garanties implicites de qualité marchande, dadéquation à un usage particulier
et dabsence de contrefaçon sont exclues.
LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES
DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une
indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous
ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris
les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
Cette limitation concerne:
•tout ce qui est relié au logiciel, aux services ou au contenu (y compris le
code) figurant sur des sites Internet tiers ou dans des programmes tiers; et
•les réclamations au titre de violation de contrat ou de garantie, ou au titre
de responsabilité stricte, de négligence ou dune autre faute dans la limite
autorisée par la loi en vigueur.
Elle sapplique également, même si Microsoft connaissait ou devrait connaître
léventualité dun tel dommage. Si votre pays nautorise pas lexclusion ou la
limitation de responsabilité pour les dommages indirects, accessoires ou de
quelque nature que ce soit, il se peut que la limitation ou lexclusion
ci-dessus ne sappliquera pas à votre égard.
EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous
pourriez avoir dautres droits prévus par les lois de votre pays. Le présent
contrat ne modifie pas les droits que vous confèrent les lois de votre pays si
celles-ci ne le permettent pas.

16
LICENSED-HARDWARE.txt Normal file
View File

@ -0,0 +1,16 @@
LICENSED HARDWARE LIST
Last Updated: 2020-05-08
Microsoft has entered into OEM Agreements with manufacturers of the following
microprocessors and microcontrollers (the “hardware”) to enable those
manufacturers to include and distribute Azure RTOS in certain hardware. If you
have obtained and/or are developing on microprocessor(s) and/or
microcontroller(s) (“hardware”) listed below you inherit the “Distribution and
Production Use” rights in Section 2 of the Microsoft Software License Terms for
Microsoft Azure RTOS. If hardware is not listed below, you do not have those
rights.
--------------------------------------------------------------------------------
More coming soon. Please check back frequently for updates.

3
README.md Executable file
View File

@ -0,0 +1,3 @@
# NetX
TODO: Description here

1
TODO Normal file
View File

@ -0,0 +1 @@
* exFAT is still in here... do we need to remove it?

321
common/CMakeLists.txt Normal file
View File

@ -0,0 +1,321 @@
target_sources(${PROJECT_NAME} PRIVATE
# {{BEGIN_TARGET_SOURCES}}
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_announce_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_dynamic_entries_invalidate.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_dynamic_entry_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_entry_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_gratuitous_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_hardware_address_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_ip_address_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_packet_deferred_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_packet_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_periodic_update.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_probe_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_queue_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_static_entries_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_static_entry_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_arp_static_entry_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_checksum_compute.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_packet_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_ping.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_icmp_queue_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_interface_report_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_loopback_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_loopback_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_multicast_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_multicast_interface_join.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_multicast_join.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_multicast_leave.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_packet_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_periodic_processing.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_igmp_queue_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_address_change_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_address_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_deferred_link_status_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_delete_queue_clear.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_driver_deferred_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_driver_deferred_processing.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_driver_deferred_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_driver_direct_command.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_driver_interface_direct_command.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_driver_link_status_event.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_forward_packet_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_forwarding_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_forwarding_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_fragment_assembly.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_fragment_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_fragment_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_fragment_packet.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_fragment_timeout_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_gateway_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_interface_address_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_interface_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_interface_attach.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_interface_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_interface_status_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_link_status_change_notify_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_loopback_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_packet_deferred_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_packet_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_periodic_timer_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_raw_packet_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_raw_packet_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_raw_packet_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_raw_packet_interface_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_raw_packet_processing.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_raw_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_raw_packet_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_route_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_static_route_add.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_static_route_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_status_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ip_thread_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_copy.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_data_append.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_data_extract_offset.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_data_retrieve.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_length_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_pool_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_pool_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_pool_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_pool_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_pool_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_release.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_packet_transmit_release.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_ram_network_driver.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_packet_deferred_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_packet_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_periodic_update.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_rarp_queue_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_system_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_checksum.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_cleanup_deferred.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_client_bind_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_client_socket_bind.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_client_socket_connect.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_client_socket_port_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_client_socket_unbind.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_connect_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_deferred_cleanup_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_disconnect_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_fast_periodic_processing.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_fast_periodic_timer_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_free_port_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_mss_option_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_no_connection_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_packet_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_packet_send_ack.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_packet_send_fin.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_packet_send_rst.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_packet_send_syn.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_periodic_processing.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_queue_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_receive_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_accept.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_listen.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_relisten.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_unaccept.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_unlisten.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_bytes_available.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_connection_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_disconnect.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_disconnect_complete_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_establish_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_mss_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_mss_peer_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_mss_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_packet_process.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_peer_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_receive_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_receive_queue_flush.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_retransmit.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_ack_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_closing.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_data_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_established.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_fin_wait1.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_fin_wait2.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_last_ack.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_syn_received.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_syn_sent.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_transmit_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_state_wait.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_thread_resume.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_thread_suspend.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_timed_wait_callback.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_transmit_configure.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_transmit_queue_flush.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_window_update_notify_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_transmit_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_trace_event_insert.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_trace_event_update.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_trace_object_register.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_trace_object_unregister.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_bind_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_free_port_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_packet_info_extract.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_receive_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_bind.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_bytes_available.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_checksum_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_checksum_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_interface_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_port_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_receive_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_unbind.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_source_extract.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_utility.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_dynamic_entries_invalidate.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_dynamic_entry_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_gratuitous_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_hardware_address_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_ip_address_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_static_entries_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_static_entry_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_arp_static_entry_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_icmp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_icmp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_icmp_ping.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_igmp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_igmp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_igmp_loopback_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_igmp_loopback_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_igmp_multicast_interface_join.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_igmp_multicast_join.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_igmp_multicast_leave.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_address_change_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_address_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_driver_direct_command.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_driver_interface_direct_command.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_forwarding_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_forwarding_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_fragment_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_fragment_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_gateway_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_interface_address_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_interface_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_interface_attach.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_interface_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_interface_status_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_link_status_change_notify_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_raw_packet_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_raw_packet_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_raw_packet_interface_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_raw_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_raw_packet_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_static_route_add.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_static_route_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_ip_status_check.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_copy.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_data_append.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_data_extract_offset.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_data_retrieve.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_length_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_pool_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_pool_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_pool_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_release.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_packet_transmit_release.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_rarp_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_rarp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_rarp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_client_socket_bind.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_client_socket_connect.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_client_socket_port_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_client_socket_unbind.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_free_port_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_server_socket_accept.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_server_socket_listen.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_server_socket_relisten.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_server_socket_unaccept.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_server_socket_unlisten.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_bytes_available.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_disconnect.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_disconnect_complete_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_establish_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_mss_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_mss_peer_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_mss_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_peer_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_receive_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_state_wait.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_timed_wait_callback.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_transmit_configure.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_tcp_socket_window_update_notify_set.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_free_port_find.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_packet_info_extract.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_bind.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_bytes_available.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_checksum_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_checksum_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_interface_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_port_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_receive_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_send.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_socket_unbind.c
${CMAKE_CURRENT_LIST_DIR}/src/nxe_udp_source_extract.c
# {{END_TARGET_SOURCES}}
)
target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
)

2370
common/inc/nx_api.h Normal file

File diff suppressed because it is too large Load Diff

154
common/inc/nx_arp.h Normal file
View File

@ -0,0 +1,154 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_arp.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX Address Resolution Protocol component, */
/* including all data types and external references. It is assumed */
/* that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_ARP_H
#define NX_ARP_H
/* Define ARP Message format. This will get encapsulated by an Ethernet frame
as well. The Ethernet frame will typically have a 6-byte Ethernet destination
address, a 6-byte Ethernet source address, and a 2-byte Ethernet Frame type,
which is 0x0806. Regular IP frames have a frame type of 0x0800.
Byte offset Size Meaning
0 2 Hardware type (1 for Ethernet)
2 2 Protocol type (0x0800 for IP)
4 1 Number of bytes for hardware address (6 for Ethernet)
5 1 Number of bytes for IP address (4 for IP)
6 2 Operation, ARP request is 1, ARP reply is 2
8 6 Sender's Ethernet Address
14 4 Sender's IP Address
18 6 Target Ethernet Address
24 4 Target IP Address
*/
#define NX_ARP_HARDWARE_TYPE ((ULONG)0x0001)
#define NX_ARP_PROTOCOL_TYPE ((ULONG)0x0800)
#define NX_ARP_HARDWARE_SIZE ((ULONG)0x06)
#define NX_ARP_PROTOCOL_SIZE ((ULONG)0x04)
#define NX_ARP_OPTION_REQUEST ((ULONG)0x0001)
#define NX_ARP_OPTION_RESPONSE ((ULONG)0x0002)
#define NX_ARP_MESSAGE_SIZE 28
/* Define the ARP defend interval. The default value is 10 seconds. */
#ifndef NX_ARP_DEFEND_INTERVAL
#define NX_ARP_DEFEND_INTERVAL 10
#endif /* NX_ARP_DEFEND_INTERVAL */
/* Define ARP function prototypes. */
VOID _nx_arp_initialize(VOID);
UINT _nx_arp_dynamic_entries_invalidate(NX_IP *ip_ptr);
UINT _nx_arp_dynamic_entry_set(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw);
UINT _nx_arp_enable(NX_IP *ip_ptr, VOID *arp_cache_memory, ULONG arp_cache_size);
UINT _nx_arp_gratuitous_send(NX_IP *ip_ptr, VOID (*response_handler)(NX_IP *ip_ptr, NX_PACKET *packet_ptr));
UINT _nx_arp_hardware_address_find(NX_IP *ip_ptr, ULONG ip_address,
ULONG *physical_msw, ULONG *physical_lsw);
UINT _nx_arp_info_get(NX_IP *ip_ptr, 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);
UINT _nx_arp_ip_address_find(NX_IP *ip_ptr, ULONG *ip_address,
ULONG physical_msw, ULONG physical_lsw);
VOID _nx_arp_queue_process(NX_IP *ip_ptr);
UINT _nx_arp_static_entries_delete(NX_IP *ip_ptr);
UINT _nx_arp_static_entry_create(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw);
UINT _nx_arp_static_entry_delete(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw);
UINT _nx_arp_entry_allocate(NX_IP *ip_ptr, NX_ARP **arp_ptr);
VOID _nx_arp_packet_send(NX_IP *ip_ptr, ULONG destination_ip, NX_INTERFACE *nx_interface);
VOID _nx_arp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_arp_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_arp_periodic_update(NX_IP *ip_ptr);
UINT _nx_arp_probe_send(NX_IP *ip_ptr, UINT interface_index, ULONG probe_address);
UINT _nx_arp_announce_send(NX_IP *ip_ptr, UINT interface_index);
/* Define error checking shells for ARP services. These are only referenced by the
application. */
UINT _nxe_arp_dynamic_entries_invalidate(NX_IP *ip_ptr);
UINT _nxe_arp_dynamic_entry_set(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw);
UINT _nxe_arp_enable(NX_IP *ip_ptr, VOID *arp_cache_memory, ULONG arp_cache_size);
UINT _nxe_arp_gratuitous_send(NX_IP *ip_ptr, VOID (*response_handler)(NX_IP *ip_ptr, NX_PACKET *packet_ptr));
UINT _nxe_arp_hardware_address_find(NX_IP *ip_ptr, ULONG ip_address,
ULONG *physical_msw, ULONG *physical_lsw);
UINT _nxe_arp_info_get(NX_IP *ip_ptr, 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);
UINT _nxe_arp_ip_address_find(NX_IP *ip_ptr, ULONG *ip_address,
ULONG physical_msw, ULONG physical_lsw);
VOID _nxe_arp_queue_process(NX_IP *ip_ptr);
UINT _nxe_arp_static_entries_delete(NX_IP *ip_ptr);
UINT _nxe_arp_static_entry_create(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw);
UINT _nxe_arp_static_entry_delete(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw);
/* ARP management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_ARP_INIT
#define ARP_DECLARE
#else
#define ARP_DECLARE extern
#endif
#endif

186
common/inc/nx_icmp.h Normal file
View File

@ -0,0 +1,186 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_icmp.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX Internet Control Message Protocol (ICMP) */
/* component, including all data types and external references. It is */
/* assumed that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_ICMP_H
#define NX_ICMP_H
/* Define ICMP types and codes. */
#define NX_ICMP_ECHO_REPLY_TYPE 0
#define NX_ICMP_DEST_UNREACHABLE_TYPE 3
#define NX_ICMP_SOURCE_QUENCH_TYPE 4
#define NX_ICMP_REDIRECT_TYPE 5
#define NX_ICMP_ECHO_REQUEST_TYPE 8
#define NX_ICMP_TIME_EXCEEDED_TYPE 11
#define NX_ICMP_PARAMETER_PROB_TYPE 12
#define NX_ICMP_TIMESTAMP_REQ_TYPE 13
#define NX_ICMP_TIMESTAMP_REP_TYPE 14
#define NX_ICMP_ADDRESS_MASK_REQ_TYPE 17
#define NX_ICMP_ADDRESS_MASK_REP_TYPE 18
#define NX_ICMP_NETWORK_UNREACH_CODE 0
#define NX_ICMP_HOST_UNREACH_CODE 1
#define NX_ICMP_PROTOCOL_UNREACH_CODE 2
#define NX_ICMP_PORT_UNREACH_CODE 3
#define NX_ICMP_FRAMENT_NEEDED_CODE 4
#define NX_ICMP_SOURCE_ROUTE_CODE 5
#define NX_ICMP_NETWORK_UNKNOWN_CODE 6
#define NX_ICMP_HOST_UNKNOWN_CODE 7
#define NX_ICMP_SOURCE_ISOLATED_CODE 8
#define NX_ICMP_NETWORK_PROHIBIT_CODE 9
#define NX_ICMP_HOST_PROHIBIT_CODE 10
#define NX_ICMP_NETWORK_SERVICE_CODE 11
#define NX_ICMP_HOST_SERVICE_CODE 12
/* Define Basic ICMP packet header data type. This will be used to
build new ICMP packets and to examine incoming packets into NetX. */
typedef struct NX_ICMP_HEADER_STRUCT
{
/* Define the first 32-bit word of the ICMP header. This word contains
the following information:
bits 31-24 ICMP 8-bit type defined as follows:
Type Field ICMP Message Type
0 Echo Reply
3 Destination Unreachable
4 Source Quench
5 Redirect (change a route)
8 Echo Request
11 Time exceeded for Datagram
12 Parameter Problem on a Datagram
13 Timestamp Request
14 Timestamp Reply
17 Address Mask Request
18 Address Mask Reply
bits 23-16 ICMP 8-bit code defined as follows:
Code Field ICMP Code Meaning
0 Network unreachable
1 Host unreachable
2 Protocol unreachable
3 Port unreachable
4 Fragmentation needed and DF is set
5 Source route failed
6 Destination network unknown
7 Destination host unknown
8 Source host isolated
9 Communication with destination network
administratively prohibited
10 Communication with destination host
administratively prohibited
11 Network unreachable for type of service
12 Host unreachable for type of service
bits 15-0 ICMP 16-bit checksum
*/
ULONG nx_icmp_header_word_0;
/* Define the second and final word of the ICMP header. This word contains
the following information:
bits 31-16 ICMP 16-bit Identification
bits 15-0 ICMP 16-bit Sequence Number
*/
ULONG nx_icmp_header_word_1;
} NX_ICMP_HEADER;
/* Define the ICMP echo request header message size. */
#define NX_ICMP_HEADER_SIZE sizeof(NX_ICMP_HEADER)
/* Define ICMP function prototypes. */
UINT _nx_icmp_enable(NX_IP *ip_ptr);
UINT _nx_icmp_info_get(NX_IP *ip_ptr, ULONG *pings_sent, ULONG *ping_timeouts,
ULONG *ping_threads_suspended, ULONG *ping_responses_received,
ULONG *icmp_checksum_errors, ULONG *icmp_unhandled_messages);
UINT _nx_icmp_ping(NX_IP *ip_ptr, ULONG ip_address, CHAR *data, ULONG data_size,
NX_PACKET **response_ptr, ULONG wait_option);
VOID _nx_icmp_initialize(VOID);
VOID _nx_icmp_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_icmp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_icmp_queue_process(NX_IP *ip_ptr);
VOID _nx_icmp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
ULONG _nx_icmp_checksum_compute(NX_PACKET *packet_ptr);
/* Define error checking shells for API services. These are only referenced by the
application. */
UINT _nxe_icmp_enable(NX_IP *ip_ptr);
UINT _nxe_icmp_info_get(NX_IP *ip_ptr, ULONG *pings_sent, ULONG *ping_timeouts,
ULONG *ping_threads_suspended, ULONG *ping_responses_received,
ULONG *icmp_checksum_errors, ULONG *icmp_unhandled_messages);
UINT _nxe_icmp_ping(NX_IP *ip_ptr, ULONG ip_address, CHAR *data, ULONG data_size,
NX_PACKET **response_ptr, ULONG wait_option);
/* ICMP component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_ICMP_INIT
#define ICMP_DECLARE
#else
#define ICMP_DECLARE extern
#endif
#endif

211
common/inc/nx_igmp.h Normal file
View File

@ -0,0 +1,211 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_igmp.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX Internet Group Management Protocol (IGMP)*/
/* component, including all data types and external references. It is */
/* assumed that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_IGMP_H
#define NX_IGMP_H
/* Define IGMP types and codes. */
/* IGMPv2 combines version field with the type field ffectively, and calls the 8 bit
field the Type field. IGMPv2 uses Type 0x11, 0x16, and 0x17 in this field, while
IGMPv1 uses Type 1 and 2 in the lower 4 bits, combined with version 1 in the upper 4 bits
for 0x11 and 0x12 as the possible values. */
/* Define the IGMP version in the IGMP header. */
#define NX_IGMP_VERSION 0x10000000
/* Define the numeric version of IGMP protocol used by NetX. */
#define NX_IGMP_HOST_VERSION_1 1
#define NX_IGMP_HOST_VERSION_2 2
/* Define the IGMP query message type and mask in the IGMP header. */
#define NX_IGMP_ROUTER_QUERY_TYPE 0x01000000
#define NX_IGMP_TYPE_MASK 0x0F000000
/* Define the IGMPv1 type for membership join reports. */
#define NX_IGMP_HOST_RESPONSE_TYPE 0x02000000
/* Define IGMPv2 types for membership join and leave reports. */
#define NX_IGMP_HOST_V2_JOIN_TYPE 0x16000000
#define NX_IGMP_HOST_V2_LEAVE_TYPE 0x17000000
/* Define the IGMPv2 type mask in the IGMP header. */
#define NX_IGMPV2_TYPE_MASK 0xFF000000
/* Define the IGMPv2 maximum response time mask in the IGMP header. Max value is 0x64,
left intentionally blank in IGMPv1 queries and all IGMP reports. Maximum response time
is in tenth's of a second. */
#define NX_IGMP_MAX_RESP_TIME_MASK 0x00FF0000
/* For IGMPv1 only, define the IGMP maximum delay time to 10 seconds as per RFC 1112. This is achieved if
the slow NetX IP periodic thread timer executes every second (e.g. NX_IP_PERIODIC_RATE is set to 100)
and the threadx timer interrupt occurs every 10 ms). */
#define NX_IGMP_MAX_UPDATE_TIME 10
/* Define the time to live for IGMP packets. RFC 1112 and 2236 specify
time to live should be set at 1. */
#define NX_IGMP_TTL 1
/* Define the mask for IGMPv1 packets' type field. */
#define NX_IGMP_TYPE_MASK 0x0F000000
/* Define the IP "all hosts" multicast address. */
#define NX_ALL_HOSTS_ADDRESS IP_ADDRESS(224, 0, 0, 1)
/* Define the IP "all routers" multicast address. */
#define NX_ALL_ROUTERS_ADDRESS IP_ADDRESS(224, 0, 0, 2)
/* Define Basic IGMP packet header data type. This will be used to
build new IGMP packets and to examine incoming IGMP queries sent
to NetX. */
typedef struct NX_IGMP_HEADER_STRUCT
{
/* Define the first 32-bit word of the IGMP header. This word contains
the following information:
bits 31-28 IGMP 4-bit version (Version 1)
bits 27-24 IGMP 4-bit type defined as follows:
Type Field IGMP Message Type
1 Router Query Request
2 Host Query Response
bits 15-0 IGMP 16-bit checksum
*/
ULONG nx_igmp_header_word_0;
/* Define the second and final word of the IGMP header. This word contains
the following information:
bits 31-0 32-bit group address (class D IP address)
*/
ULONG nx_igmp_header_word_1;
} NX_IGMP_HEADER;
/* Define the IGMP query response message size. */
#define NX_IGMP_HEADER_SIZE sizeof(NX_IGMP_HEADER)
/* Define IGMP function prototypes. */
UINT _nx_igmp_enable(NX_IP *ip_ptr);
UINT _nx_igmp_info_get(NX_IP *ip_ptr, ULONG *igmp_reports_sent, ULONG *igmp_queries_received,
ULONG *igmp_checksum_errors, ULONG *current_groups_joined);
UINT _nx_igmp_loopback_disable(NX_IP *ip_ptr);
UINT _nx_igmp_loopback_enable(NX_IP *ip_ptr);
UINT _nx_igmp_multicast_join(NX_IP *ip_ptr, ULONG group_address);
UINT _nx_igmp_multicast_interface_join(NX_IP *ip_ptr, ULONG group_address, UINT nx_interface_index);
UINT _nx_igmp_multicast_leave(NX_IP *ip_ptr, ULONG group_address);
VOID _nx_igmp_initialize(VOID);
UINT _nx_igmp_interface_report_send(NX_IP *ip_ptr, ULONG group_address, UINT interface_index, UINT is_joining);
VOID _nx_igmp_periodic_processing(NX_IP *ip_ptr);
VOID _nx_igmp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_igmp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_igmp_queue_process(NX_IP *ip_ptr);
UINT _nx_igmp_multicast_check(NX_IP *ip_ptr, ULONG group_address, NX_INTERFACE *nx_interface);
/* Define error checking shells for API services. These are only referenced by the
application. */
UINT _nxe_igmp_enable(NX_IP *ip_ptr);
UINT _nxe_igmp_info_get(NX_IP *ip_ptr, ULONG *igmp_reports_sent, ULONG *igmp_queries_received,
ULONG *igmp_checksum_errors, ULONG *current_groups_joined);
UINT _nxe_igmp_loopback_disable(NX_IP *ip_ptr);
UINT _nxe_igmp_loopback_enable(NX_IP *ip_ptr);
UINT _nxe_igmp_multicast_join(NX_IP *ip_ptr, ULONG group_address);
UINT _nxe_igmp_multicast_interface_join(NX_IP *ip_ptr, ULONG group_address, UINT nx_interface_index);
UINT _nxe_igmp_multicast_leave(NX_IP *ip_ptr, ULONG group_address);
/* IGMP component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_IGMP_INIT
#define IGMP_DECLARE
#else
#define IGMP_DECLARE extern
#endif
#endif

300
common/inc/nx_ip.h Normal file
View File

@ -0,0 +1,300 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_ip.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX Internet Protocol component, */
/* including all data types and external references. It is assumed */
/* that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_IP_H
#define NX_IP_H
/* Define IP constants. */
#define NX_IP_ID ((ULONG)0x49502020)
/* Define basic IP Header constant. */
#define NX_IP_VERSION ((ULONG)0x45000000) /* Version 4, Length of 5 */
/* Define the mask for the IP header length field. */
#define NX_IP_LENGTH_MASK ((ULONG)0x0F000000) /* Mask for length bit */
#define NX_IP_NORMAL_LENGTH 5 /* Normal IP header length */
/* Define IP fragmenting information. */
#define NX_IP_DONT_FRAGMENT ((ULONG)0x00004000) /* Don't fragment bit */
#define NX_IP_MORE_FRAGMENT ((ULONG)0x00002000) /* More fragments */
#define NX_IP_FRAGMENT_MASK ((ULONG)0x00003FFF) /* Mask for fragment bits */
#define NX_IP_OFFSET_MASK ((ULONG)0x00001FFF) /* Mask for fragment offset */
#define NX_IP_ALIGN_FRAGS 8 /* Fragment alignment */
/* Define IP event flags. These events are processed by the IP thread. */
#define NX_IP_ALL_EVENTS ((ULONG)0xFFFFFFFF) /* All event flags */
#define NX_IP_PERIODIC_EVENT ((ULONG)0x00000001) /* Periodic ARP event */
#define NX_IP_UNFRAG_EVENT ((ULONG)0x00000002) /* Unfragment event */
#define NX_IP_ICMP_EVENT ((ULONG)0x00000004) /* ICMP message event */
#define NX_IP_RECEIVE_EVENT ((ULONG)0x00000008) /* IP receive packet event */
#define NX_IP_ARP_REC_EVENT ((ULONG)0x00000010) /* ARP deferred receive event */
#define NX_IP_RARP_REC_EVENT ((ULONG)0x00000020) /* RARP deferred receive event */
#define NX_IP_IGMP_EVENT ((ULONG)0x00000040) /* IGMP message event */
#define NX_IP_TCP_EVENT ((ULONG)0x00000080) /* TCP message event */
#define NX_IP_TCP_FAST_EVENT ((ULONG)0x00000100) /* Fast TCP timer event */
#define NX_IP_DRIVER_PACKET_EVENT ((ULONG)0x00000200) /* Driver Deferred packet event */
#define NX_IP_IGMP_ENABLE_EVENT ((ULONG)0x00000400) /* IGMP enable event */
#define NX_IP_DRIVER_DEFERRED_EVENT ((ULONG)0x00000800) /* Driver deferred processing */
/* event */
#define NX_IP_TCP_CLEANUP_DEFERRED ((ULONG)0x00001000) /* Deferred TCP cleanup event */
#define NX_IP_LINK_STATUS_EVENT ((ULONG)0x00002000) /* Link status change event */
#ifndef NX_IP_DEBUG_LOG_SIZE
#define NX_IP_DEBUG_LOG_SIZE 100 /* Maximum size of optional log */
#endif
/* Define the amount of time to sleep in nx_ip_(interface_)status_check */
#ifndef NX_IP_STATUS_CHECK_WAIT_TIME
#define NX_IP_STATUS_CHECK_WAIT_TIME 1
#endif /* NX_IP_STATUS_CHECK_WAIT_TIME */
/* Define Basic Internet packet header data type. This will be used to
build new IP packets and to examine incoming packets into NetX. */
typedef struct NX_IP_HEADER_STRUCT
{
/* Define the first 32-bit word of the IP header. This word contains
the following information:
bits 31-28 IP Version = 0x4 (IP Version4)
bits 27-24 IP Header Length of 32-bit words (5 if no options)
bits 23-16 IP Type of Service, where 0x00 -> Normal
0x10 -> Minimize Delay
0x08 -> Maximize Throughput
0x04 -> Maximize Reliability
0x02 -> Minimize Monetary Cost
bits 15-0 IP Datagram length in bytes
*/
ULONG nx_ip_header_word_0;
/* Define the second word of the IP header. This word contains
the following information:
bits 31-16 IP Packet Identification (just an incrementing number)
bits 15-0 IP Flags and Fragment Offset (used for IP fragmenting)
bit 15 Zero
bit 14 Don't Fragment
bit 13 More Fragments
bits 12-0 (Fragment offset)/8
*/
ULONG nx_ip_header_word_1;
/* Define the third word of the IP header. This word contains
the following information:
bits 31-24 IP Time-To-Live (maximum number of routers
packet can traverse before being
thrown away. Default values are typically
32 or 64)
bits 23-16 IP Protocol, where 0x01 -> ICMP Messages
0x02 -> IGMP Messages
0x06 -> TCP Messages
0x11 -> UDP Messages
bits 15-0 IP Checksum
*/
ULONG nx_ip_header_word_2;
/* Define the source IP address. */
ULONG nx_ip_header_source_ip;
/* Define the destination IP address. */
ULONG nx_ip_header_destination_ip;
} NX_IP_HEADER;
/* Define IP function prototypes. */
UINT _nx_ip_address_change_notify(NX_IP *ip_ptr, VOID (*ip_address_change_notify)(NX_IP *, VOID *), VOID *additional_info);
UINT _nx_ip_address_get(NX_IP *ip_ptr, ULONG *ip_address, ULONG *network_mask);
UINT _nx_ip_address_set(NX_IP *ip_ptr, ULONG ip_address, ULONG network_mask);
UINT _nx_ip_interface_address_get(NX_IP *ip_ptr, ULONG interface_index, ULONG *ip_address, ULONG *network_mask);
UINT _nx_ip_interface_address_set(NX_IP *ip_ptr, ULONG interface_index, ULONG ip_address, ULONG network_mask);
UINT _nx_ip_interface_info_get(NX_IP *ip_ptr, UINT interface_index, CHAR **interface_name, ULONG *ip_address,
ULONG *network_mask, ULONG *mtu_size, ULONG *phsyical_address_msw,
ULONG *physical_address_lsw);
UINT _nx_ip_interface_status_check(NX_IP *ip_ptr, UINT interface_index, ULONG needed_status, ULONG *actual_status,
ULONG wait_option);
UINT _nx_ip_create(NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask,
NX_PACKET_POOL *default_pool,
VOID (*ip_link_driver)(NX_IP_DRIVER *),
VOID *memory_ptr, ULONG memory_size, UINT priority);
UINT _nx_ip_delete(NX_IP *ip_ptr);
VOID _nx_ip_delete_queue_clear(NX_PACKET *head_ptr);
VOID _nx_ip_deferred_link_status_process(NX_IP *ip_ptr);
VOID _nx_ip_driver_link_status_event(NX_IP *ip_ptr, UINT interface_index);
VOID _nx_ip_driver_deferred_enable(NX_IP *ip_ptr, VOID (*driver_deferred_packet_handler)(NX_IP *ip_ptr, NX_PACKET *packet_ptr));
VOID _nx_ip_driver_deferred_processing(NX_IP *ip_ptr);
VOID _nx_ip_driver_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
UINT _nx_ip_driver_direct_command(NX_IP *ip_ptr, UINT command, ULONG *return_value_ptr);
UINT _nx_ip_driver_interface_direct_command(NX_IP *ip_ptr, UINT command, UINT interface_index, ULONG *return_value_ptr);
UINT _nx_ip_forwarding_disable(NX_IP *ip_ptr);
UINT _nx_ip_forwarding_enable(NX_IP *ip_ptr);
UINT _nx_ip_fragment_disable(NX_IP *ip_ptr);
UINT _nx_ip_fragment_enable(NX_IP *ip_ptr);
UINT _nx_ip_gateway_address_set(NX_IP *ip_ptr, ULONG ip_address);
UINT _nx_ip_info_get(NX_IP *ip_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);
UINT _nx_ip_interface_attach(NX_IP *ip_ptr, CHAR *interface_name, ULONG ip_address, ULONG network_mask, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *));
UINT _nx_ip_raw_packet_disable(NX_IP *ip_ptr);
UINT _nx_ip_raw_packet_enable(NX_IP *ip_ptr);
UINT _nx_ip_raw_packet_receive(NX_IP *ip_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
UINT _nx_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
ULONG destination_ip, ULONG type_of_service);
UINT _nx_ip_raw_packet_interface_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
ULONG destination_ip, UINT interface_index, ULONG type_of_service);
VOID _nx_ip_initialize(VOID);
VOID _nx_ip_forward_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_ip_fragment_timeout_check(NX_IP *ip_ptr);
VOID _nx_ip_loopback_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT packet_release);
ULONG _nx_ip_route_find(NX_IP *ip_ptr, ULONG destination_address, NX_INTERFACE **nx_ip_interface, ULONG *next_hop_address);
VOID _nx_ip_periodic_timer_entry(ULONG ip_address);
VOID _nx_ip_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG destination_ip, ULONG type_of_service, ULONG time_to_live, ULONG protocol, ULONG fragment);
VOID _nx_ip_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_ip_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
UINT _nx_ip_status_check(NX_IP *ip_ptr, ULONG needed_status, ULONG *actual_status,
ULONG wait_option);
UINT _nx_ip_link_status_change_notify_set(NX_IP *ip_ptr, VOID (*link_status_change_notify)(NX_IP *ip_ptr, UINT interface_index, UINT link_up));
VOID _nx_ip_thread_entry(ULONG ip_ptr_value);
VOID _nx_ip_raw_packet_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_ip_raw_packet_processing(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_ip_fragment_packet(struct NX_IP_DRIVER_STRUCT *driver_req_ptr);
VOID _nx_ip_fragment_assembly(NX_IP *ip_ptr);
UINT _nx_ip_static_route_add(NX_IP *ip_ptr, ULONG network_address, ULONG net_mask, ULONG next_hop);
UINT _nx_ip_static_route_delete(NX_IP *ip_ptr, ULONG network_address, ULONG net_mask);
ULONG _nx_ip_static_route_find(NX_IP *ip_ptr, ULONG destination_address);
/* Define error checking shells for API services. These are only referenced by the
application. */
UINT _nxe_ip_address_change_notify(NX_IP *ip_ptr, VOID (*ip_address_change_notify)(NX_IP *, VOID *), VOID *additional_info);
UINT _nxe_ip_address_get(NX_IP *ip_ptr, ULONG *ip_address, ULONG *network_mask);
UINT _nxe_ip_address_set(NX_IP *ip_ptr, ULONG ip_address, ULONG network_mask);
UINT _nxe_ip_interface_address_get(NX_IP *ip_ptr, ULONG interface_index, ULONG *ip_address, ULONG *network_mask);
UINT _nxe_ip_interface_address_set(NX_IP *ip_ptr, ULONG interface_index, ULONG ip_address, ULONG network_mask);
UINT _nxe_ip_interface_info_get(NX_IP *ip_ptr, UINT interface_index, CHAR **interface_name, ULONG *ip_address,
ULONG *network_mask, ULONG *mtu_size, ULONG *phsyical_address_msw,
ULONG *physical_address_lsw);
UINT _nxe_ip_interface_status_check(NX_IP *ip_ptr, UINT interface_index, ULONG needed_status, ULONG *actual_status,
ULONG wait_option);
UINT _nxe_ip_create(NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask,
NX_PACKET_POOL *default_pool,
VOID (*ip_link_driver)(NX_IP_DRIVER *),
VOID *memory_ptr, ULONG memory_size, UINT priority, UINT ip_control_block_size);
UINT _nxe_ip_delete(NX_IP *ip_ptr);
UINT _nxe_ip_driver_direct_command(NX_IP *ip_ptr, UINT command, ULONG *return_value_ptr);
UINT _nxe_ip_driver_interface_direct_command(NX_IP *ip_ptr, UINT command, UINT interface_index, ULONG *return_value_ptr);
UINT _nxe_ip_forwarding_disable(NX_IP *ip_ptr);
UINT _nxe_ip_forwarding_enable(NX_IP *ip_ptr);
UINT _nxe_ip_fragment_disable(NX_IP *ip_ptr);
UINT _nxe_ip_fragment_enable(NX_IP *ip_ptr);
UINT _nxe_ip_gateway_address_set(NX_IP *ip_ptr, ULONG ip_address);
UINT _nxe_ip_info_get(NX_IP *ip_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);
UINT _nxe_ip_interface_attach(NX_IP *ip_ptr, CHAR *interface_name, ULONG ip_address, ULONG network_mask, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *));
UINT _nxe_ip_raw_packet_disable(NX_IP *ip_ptr);
UINT _nxe_ip_raw_packet_enable(NX_IP *ip_ptr);
UINT _nxe_ip_raw_packet_receive(NX_IP *ip_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
UINT _nxe_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET **packet_ptr_ptr,
ULONG destination_ip, ULONG type_of_service);
UINT _nxe_ip_raw_packet_interface_send(NX_IP *ip_ptr, NX_PACKET **packet_ptr_ptr,
ULONG destination_ip, UINT interface_index, ULONG type_of_service);
UINT _nxe_ip_status_check(NX_IP *ip_ptr, ULONG needed_status, ULONG *actual_status,
ULONG wait_option);
UINT _nxe_ip_link_status_change_notify_set(NX_IP *ip_ptr, VOID (*link_status_change_notify)(NX_IP *ip_ptr, UINT interface_index, UINT link_up));
UINT _nxe_ip_static_route_add(NX_IP *ip_ptr, ULONG network_address, ULONG net_mask, ULONG next_hop);
UINT _nxe_ip_static_route_delete(NX_IP *ip_ptr, ULONG network_address, ULONG net_mask);
UINT _nxe_ip_static_routing_disable(NX_IP *ip_ptr);
UINT _nxe_ip_static_routing_enable(NX_IP *ip_ptr);
/* IP component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_IP_INIT
#define IP_DECLARE
#else
#define IP_DECLARE extern
#endif
/* Define the head pointer of the created IP list. */
IP_DECLARE NX_IP *_nx_ip_created_ptr;
/* Define the number of created IP instances. */
IP_DECLARE ULONG _nx_ip_created_count;
#endif

146
common/inc/nx_packet.h Normal file
View File

@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Packet Pool Management (Packet) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_packet.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX packet memory management component, */
/* including all data types and external references. It is assumed */
/* that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_PAC_H
#define NX_PAC_H
#define NX_PACKET_POOL_ID ((ULONG)0x5041434B)
/* Define constants for packet free, allocated, enqueued, and driver transmit done.
These will be used in the nx_packet_tcp_queue_next field to indicate the state of
the packet. */
#define NX_PACKET_FREE ((ULONG)0xFFFFFFFF) /* Packet is available and in the pool */
#define NX_PACKET_ALLOCATED ((ULONG)0xAAAAAAAA) /* Packet has been allocated */
#define NX_PACKET_ENQUEUED ((ULONG)0xEEEEEEEE) /* Packet is the tail of TCP queue. */
/* A value that is none of the above */
/* also indicates the packet is in a */
/* TCP queue */
/* Define the constant for driver done and receive packet is available. These will be
used in the nx_packet_queue_next field to indicate the state of a TCP packet. */
#define NX_DRIVER_TX_DONE ((ULONG)0xDDDDDDDD) /* Driver has sent the TCP packet */
#define NX_PACKET_READY ((ULONG)0xBBBBBBBB) /* Packet is ready for retrieval */
/* Define packet pool management function prototypes. */
UINT _nx_packet_allocate(NX_PACKET_POOL *pool_ptr, NX_PACKET **packet_ptr,
ULONG packet_type, ULONG wait_option);
UINT _nx_packet_copy(NX_PACKET *packet_ptr, NX_PACKET **new_packet_ptr,
NX_PACKET_POOL *pool_ptr, ULONG wait_option);
UINT _nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size,
NX_PACKET_POOL *pool_ptr, ULONG wait_option);
UINT _nx_packet_data_extract_offset(NX_PACKET *packet_ptr, ULONG offset, VOID *buffer_start,
ULONG buffer_length, ULONG *bytes_copied);
UINT _nx_packet_data_retrieve(NX_PACKET *packet_ptr, VOID *buffer_start, ULONG *bytes_copied);
UINT _nx_packet_length_get(NX_PACKET *packet_ptr, ULONG *length);
UINT _nx_packet_pool_create(NX_PACKET_POOL *pool_ptr, CHAR *name, ULONG payload_size,
VOID *memory_ptr, ULONG memory_size);
UINT _nx_packet_pool_delete(NX_PACKET_POOL *pool_ptr);
UINT _nx_packet_pool_info_get(NX_PACKET_POOL *pool_ptr, ULONG *total_packets, ULONG *free_packets,
ULONG *empty_pool_requests, ULONG *empty_pool_suspensions,
ULONG *invalid_packet_releases);
UINT _nx_packet_release(NX_PACKET *packet_ptr);
UINT _nx_packet_transmit_release(NX_PACKET *packet_ptr);
VOID _nx_packet_pool_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_packet_pool_initialize(VOID);
/* Define error checking shells for API services. These are only referenced by the
application. */
UINT _nxe_packet_allocate(NX_PACKET_POOL *pool_ptr, NX_PACKET **packet_ptr,
ULONG packet_type, ULONG wait_option);
UINT _nxe_packet_copy(NX_PACKET *packet_ptr, NX_PACKET **new_packet_ptr,
NX_PACKET_POOL *pool_ptr, ULONG wait_option);
UINT _nxe_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size,
NX_PACKET_POOL *pool_ptr, ULONG wait_option);
UINT _nxe_packet_data_extract_offset(NX_PACKET *packet_ptr, ULONG offset, VOID *buffer_start,
ULONG buffer_length, ULONG *bytes_copied);
UINT _nxe_packet_data_retrieve(NX_PACKET *packet_ptr, VOID *buffer_start, ULONG *bytes_copied);
UINT _nxe_packet_length_get(NX_PACKET *packet_ptr, ULONG *length);
UINT _nxe_packet_pool_create(NX_PACKET_POOL *pool_ptr, CHAR *name, ULONG payload_size,
VOID *memory_ptr, ULONG memory_size, UINT pool_control_block_size);
UINT _nxe_packet_pool_delete(NX_PACKET_POOL *pool_ptr);
UINT _nxe_packet_pool_info_get(NX_PACKET_POOL *pool_ptr, ULONG *total_packets, ULONG *free_packets,
ULONG *empty_pool_requests, ULONG *empty_pool_suspensions,
ULONG *invalid_packet_releases);
UINT _nxe_packet_release(NX_PACKET **packet_ptr_ptr);
UINT _nxe_packet_transmit_release(NX_PACKET **packet_ptr_ptr);
/* Packet pool management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_PACKET_POOL_INIT
#define PACKET_POOL_DECLARE
#else
#define PACKET_POOL_DECLARE extern
#endif
/* Define the head pointer of the created packet pool list. */
PACKET_POOL_DECLARE NX_PACKET_POOL *_nx_packet_pool_created_ptr;
/* Define the variable that holds the number of created packet pools. */
PACKET_POOL_DECLARE ULONG _nx_packet_pool_created_count;
#endif

115
common/inc/nx_rarp.h Normal file
View File

@ -0,0 +1,115 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Reverse Address Resolution Protocol (RARP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_rarp.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX Reverse Address Resolution Protocol */
/* component, including all data types and external references. It */
/* is assumed that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_RARP_H
#define NX_RARP_H
/* Define RARP Message format. This will get encapsulated by an Ethernet frame
as well. The Ethernet frame will typically have a 6-byte Ethernet destination
address, a 6-byte Ethernet source address, and a 2-byte Ethernet Frame type,
which is 0x8035. Regular IP frames have a frame type of 0x0800.
Byte offset Size Meaning
0 2 Hardware type (1 for Ethernet)
2 2 Protocol type (0x0800 for IP)
4 1 Number of bytes for hardware address (6 for Ethernet)
5 1 Number of bytes for IP address (4 for IP)
6 2 Operation, ARP request is 1, ARP reply is 2
8 6 Sender's Ethernet Address
14 4 Sender's IP Address
18 6 Target Ethernet Address
24 4 Target IP Address
*/
#define NX_RARP_HARDWARE_TYPE ((ULONG)0x0001)
#define NX_RARP_PROTOCOL_TYPE ((ULONG)0x0800)
#define NX_RARP_HARDWARE_SIZE ((ULONG)0x06)
#define NX_RARP_PROTOCOL_SIZE ((ULONG)0x04)
#define NX_RARP_OPTION_REQUEST ((ULONG)0x0003)
#define NX_RARP_OPTION_RESPONSE ((ULONG)0x0004)
#define NX_RARP_MESSAGE_SIZE 28
/* Define RARP function prototypes. */
VOID _nx_rarp_initialize(VOID);
UINT _nx_rarp_enable(NX_IP *ip_ptr);
UINT _nx_rarp_disable(NX_IP *ip_ptr);
UINT _nx_rarp_info_get(NX_IP *ip_ptr, ULONG *rarp_requests_sent, ULONG *rarp_responses_received,
ULONG *rarp_invalid_messages);
VOID _nx_rarp_packet_send(NX_IP *ip_ptr);
VOID _nx_rarp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_rarp_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_rarp_periodic_update(NX_IP *ip_ptr);
VOID _nx_rarp_queue_process(NX_IP *ip_ptr);
/* Define error checking shells for RARP services. These are only referenced by the
application. */
UINT _nxe_rarp_enable(NX_IP *ip_ptr);
UINT _nxe_rarp_disable(NX_IP *ip_ptr);
UINT _nxe_rarp_info_get(NX_IP *ip_ptr, ULONG *rarp_requests_sent, ULONG *rarp_responses_received,
ULONG *rarp_invalid_messages);
/* RARP management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_RARP_INIT
#define RARP_DECLARE
#else
#define RARP_DECLARE extern
#endif
#endif

152
common/inc/nx_system.h Normal file
View File

@ -0,0 +1,152 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** System Management (System) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_system.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX system management component, */
/* including all data types and external references. It is assumed */
/* that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_SYS_H
#define NX_SYS_H
/* Define system management function prototypes. */
VOID _nx_system_initialize(VOID);
/* Define error checking shells for API services. These are only referenced by the
application. */
/* System management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_SYSTEM_INIT
#define SYSTEM_DECLARE
#else
#define SYSTEM_DECLARE extern
#endif
/* Define the global NetX build options variables. These variables contain a bit
map representing how the NetX library was built. The following are the bit
field definitions:
_nx_system_build_options_1:
Bit(s) Meaning
31 NX_LITTLE_ENDIAN
30 NX_DISABLE_ARP_AUTO_ENTRY
29 NX_ENABLE_TCP_KEEPALIVE
28 NX_TCP_IMMEDIATE_ACK
27 NX_DRIVER_DEFERRED_PROCESSING
26 NX_DISABLE_FRAGMENTATION
25 NX_DISABLE_IP_RX_CHECKSUM
24 NX_DISABLE_IP_TX_CHECKSUM
23 NX_DISABLE_TCP_RX_CHECKSUM
22 NX_DISABLE_TCP_TX_CHECKSUM
21 NX_DISABLE_RESET_DISCONNECT
20 NX_DISABLE_RX_SIZE_CHECKING
19 NX_DISABLE_ARP_INFO
18 NX_DISABLE_IP_INFO
17 NX_DISABLE_ICMP_INFO
16 NX_DISABLE_IGMP_INFO
15 NX_DISABLE_PACKET_INFO
14 NX_DISABLE_RARP_INFO
13 NX_DISABLE_TCP_INFO
12 NX_DISABLE_UDP_INFO
3-0 NX_TCP_RETRY_SHIFT
_nx_system_build_options_2:
Bit(s) Meaning
31-16 NX_IP_PERIODIC_RATE
15-8 NX_ARP_EXPIRATION_RATE
7-0 NX_ARP_UPDATE_RATE
_nx_system_build_options_3:
Bit(s) Meaning
31-24 NX_TCP_ACK_TIMER_RATE
23-16 NX_TCP_FAST_TIMER_RATE
15-8 NX_TCP_TRANSMIT_TIMER_RATE
7-0 NX_TCP_KEEPALIVE_RETRY
_nx_system_build_options_4:
Bit(s) Meaning
31-16 NX_TCP_KEEPALIVE_INITIAL
15-8 NX_ARP_MAXIMUM_RETRIES
7-4 NX_ARP_MAX_QUEUE_DEPTH
3-0 NX_TCP_KEEPALIVE_RETRIES
_nx_system_build_options_5:
Bit(s) Meaning
31-24 NX_MAX_MULTICAST_GROUPS
23-16 NX_MAX_LISTEN_REQUESTS
15-8 NX_TCP_MAXIMUM_RETRIES
7-0 NX_TCP_MAXIMUM_TX_QUEUE
Note that values greater than the value that can be represented in the build options
bit field are represented as all ones in the bit field. For example, if NX_TCP_ACK_TIMER_RATE
is 256, the value in the bits 31-24 of _nx_system_build_options_3 is 0xFF, which is 255
decimal. */
SYSTEM_DECLARE ULONG _nx_system_build_options_1;
SYSTEM_DECLARE ULONG _nx_system_build_options_2;
SYSTEM_DECLARE ULONG _nx_system_build_options_3;
SYSTEM_DECLARE ULONG _nx_system_build_options_4;
SYSTEM_DECLARE ULONG _nx_system_build_options_5;
#endif

446
common/inc/nx_tcp.h Normal file
View File

@ -0,0 +1,446 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Transmission Control Protocol (TCP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_tcp.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX Transmission Control Protocol component, */
/* including all data types and external references. It is assumed */
/* that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_TCP_H
#define NX_TCP_H
/* Define TCP constants. */
#define NX_TCP_ID ((ULONG)0x54435020)
/* Define the TCP header typical size. */
#define NX_TCP_HEADER_SIZE ((ULONG)0x50000000) /* Typical 5 word TCP header */
#define NX_TCP_SYN_HEADER ((ULONG)0x70000000) /* SYN header with MSS option */
#define NX_TCP_HEADER_MASK ((ULONG)0xF0000000) /* TCP header size mask */
#define NX_TCP_HEADER_SHIFT 28 /* Shift down to pickup length */
/* Define the TCP header control fields. */
#define NX_TCP_CONTROL_MASK ((ULONG)0x00170000) /* ACK, RST, SYN, and FIN bits */
#define NX_TCP_URG_BIT ((ULONG)0x00200000) /* Urgent data bit */
#define NX_TCP_ACK_BIT ((ULONG)0x00100000) /* Acknowledgement bit */
#define NX_TCP_PSH_BIT ((ULONG)0x00080000) /* Push bit */
#define NX_TCP_RST_BIT ((ULONG)0x00040000) /* Reset bit */
#define NX_TCP_SYN_BIT ((ULONG)0x00020000) /* Sequence bit */
#define NX_TCP_FIN_BIT ((ULONG)0x00010000) /* Finish bit */
/* Define the MSS option for the TCP header. */
#define NX_TCP_MSS_OPTION ((ULONG)0x02040000) /* Maximum Segment Size option, 32 bits */
#define NX_TCP_RWIN_OPTION ((ULONG)0x03030000) /* 24 bits, so NOP, 0x3, 0x3, scale value */
#define NX_TCP_MSS_SIZE 1460 /* Maximum Segment Size */
#define NX_TCP_OPTION_END ((ULONG)0x00000000) /* NOPs and end of TCP options */
#define NX_TCP_EOL_KIND 0x00 /* EOL option kind */
#define NX_TCP_NOP_KIND 0x01 /* NOP option kind */
#define NX_TCP_MSS_KIND 0x02 /* MSS option kind */
#define NX_TCP_RWIN_KIND 0x03
/* Define constants for the optional TCP keepalive Timer. To enable this
feature, the TCP source must be compiled with NX_ENABLE_TCP_KEEPALIVE
defined. */
#ifndef NX_TCP_KEEPALIVE_INITIAL
#define NX_TCP_KEEPALIVE_INITIAL 7200 /* Number of seconds for initial */
#endif /* keepalive expiration, the */
/* default is 2 hours (120 min)*/
#ifndef NX_TCP_KEEPALIVE_RETRY
#define NX_TCP_KEEPALIVE_RETRY 75 /* After initial expiration, */
#endif /* retry every 75 seconds */
#ifndef NX_TCP_KEEPALIVE_RETRIES
#define NX_TCP_KEEPALIVE_RETRIES 10 /* Retry a maximum of 10 times */
#endif
#ifndef NX_TCP_MAXIMUM_TX_QUEUE
#define NX_TCP_MAXIMUM_TX_QUEUE 20 /* Maximum number of transmit */
#endif /* packets queued */
#ifndef NX_TCP_MAXIMUM_RETRIES
#define NX_TCP_MAXIMUM_RETRIES 10 /* Maximum number of transmit */
#endif /* retries allowed */
#ifndef NX_TCP_RETRY_SHIFT
#define NX_TCP_RETRY_SHIFT 0 /* Shift that is applied to */
#endif /* last timeout for back off, */
/* i.e. a value of zero means */
/* constant timeouts, a value */
/* of 1 causes each successive */
/* be multiplied by two, etc. */
/* Define the rate for the TCP fast periodic timer. This timer is used to process
delayed ACKs and packet re-transmission. Hence, it must have greater resolution
than the 200ms delayed ACK requirement. By default, the fast periodic timer is
setup on a 100ms periodic. The number supplied is used to divide the
NX_IP_PERIODIC_RATE value to actually derive the ticks. Dividing
by 10 yields a 100ms base periodic. */
#ifndef NX_TCP_FAST_TIMER_RATE
#define NX_TCP_FAST_TIMER_RATE 10
#endif
/* Define the rate for the TCP delayed ACK timer, which by default is 200ms. The
number supplied is used to divide the NX_IP_PERIODIC_RATE value to
actually derive the ticks. Dividing by 5 yields a 200ms periodic. */
#ifndef NX_TCP_ACK_TIMER_RATE
#define NX_TCP_ACK_TIMER_RATE 5
#endif
/* Define the rate for the TCP retransmit timer, which by default is set to
one second. The number supplied is used to divide the NX_IP_PERIODIC_RATE
value to actually derive the ticks. Dividing by 1 yields a 1 second periodic. */
#ifndef NX_TCP_TRANSMIT_TIMER_RATE
#define NX_TCP_TRANSMIT_TIMER_RATE 1
#endif
/* Define Basic TCP packet header data type. This will be used to
build new TCP packets and to examine incoming packets into NetX. */
typedef struct NX_TCP_HEADER_STRUCT
{
/* Define the first 32-bit word of the TCP header. This word contains
the following information:
bits 31-16 TCP 16-bit source port number
bits 15-0 TCP 16-bit destination port number
*/
ULONG nx_tcp_header_word_0;
/* Define the second word of the TCP header. This word contains
the following information:
bits 31-0 TCP 32-bit sequence number
*/
ULONG nx_tcp_sequence_number;
/* Define the third word of the TCP header. This word contains
the following information:
bits 31-0 TCP 32-bit acknowledgment number
*/
ULONG nx_tcp_acknowledgment_number;
/* Define the fourth 32-bit word of the TCP header. This word contains
the following information:
bits 31-28 TCP 4-bit header length
bits 27-22 TCP 6-bit reserved field
bit 21 TCP Urgent bit (URG)
bit 20 TCP Acknowledgement bit (ACK)
bit 19 TCP Push bit (PSH)
bit 18 TCP Reset connection bit (RST)
bit 17 TCP Synchronize sequence numbers bit (SYN)
bit 16 TCP Sender has reached the end of its byte stream (FIN)
bits 15-0 TCP 16-bit window size
*/
ULONG nx_tcp_header_word_3;
/* Define the fifth 32-bit word of the TCP header. This word contains
the following information:
bits 31-16 TCP 16-bit TCP checksum
bits 15-0 TCP 16-bit TCP urgent pointer
*/
ULONG nx_tcp_header_word_4;
} NX_TCP_HEADER;
/* Define TCP SYN packet header data type. This will be used during the
initial connection requests for NetX. */
typedef struct NX_TCP_SYN_STRUCT
{
/* Define the first 32-bit word of the TCP header. This word contains
the following information:
bits 31-16 TCP 16-bit source port number
bits 15-0 TCP 16-bit destination port number
*/
ULONG nx_tcp_header_word_0;
/* Define the second word of the TCP header. This word contains
the following information:
bits 31-0 TCP 32-bit sequence number
*/
ULONG nx_tcp_sequence_number;
/* Define the third word of the TCP header. This word contains
the following information:
bits 31-0 TCP 32-bit acknowledgment number
*/
ULONG nx_tcp_acknowledgment_number;
/* Define the fourth 32-bit word of the TCP header. This word contains
the following information:
bits 31-28 TCP 4-bit header length
bits 27-22 TCP 6-bit reserved field
bit 21 TCP Urgent bit (URG)
bit 20 TCP Acknowledgement bit (ACK)
bit 19 TCP Push bit (PSH)
bit 18 TCP Reset connection bit (RST)
bit 17 TCP Synchronize sequence numbers bit (SYN)
bit 16 TCP Sender has reached the end of its byte stream (FIN)
bits 15-0 TCP 16-bit window size
*/
ULONG nx_tcp_header_word_3;
/* Define the fifth 32-bit word of the TCP header. This word contains
the following information:
bits 31-16 TCP 16-bit TCP checksum
bits 15-0 TCP 16-bit TCP urgent pointer
*/
ULONG nx_tcp_header_word_4;
/* Define the first option word of the TCP SYN header. This word contains
the MSS option type and the MSS itself. */
ULONG nx_tcp_option_word_1;
/* Define the second option word of the TCP SYN header. This word contains
window scaling if enabled. Otherwise it signals the end of the option list. */
ULONG nx_tcp_option_word_2;
} NX_TCP_SYN;
/* Define TCP component API function prototypes. */
UINT _nx_tcp_client_socket_bind(NX_TCP_SOCKET *socket_ptr, UINT port, ULONG wait_option);
UINT _nx_tcp_client_socket_connect(NX_TCP_SOCKET *socket_ptr, ULONG server_ip, UINT server_port, ULONG wait_option);
UINT _nx_tcp_client_socket_port_get(NX_TCP_SOCKET *socket_ptr, UINT *port_ptr);
UINT _nx_tcp_client_socket_unbind(NX_TCP_SOCKET *socket_ptr);
UINT _nx_tcp_enable(NX_IP *ip_ptr);
UINT _nx_tcp_free_port_find(NX_IP *ip_ptr, UINT port, UINT *free_port_ptr);
UINT _nx_tcp_info_get(NX_IP *ip_ptr, ULONG *tcp_packets_sent, ULONG *tcp_bytes_sent,
ULONG *tcp_packets_received, ULONG *tcp_bytes_received,
ULONG *tcp_invalid_packets, ULONG *tcp_receive_packets_dropped,
ULONG *tcp_checksum_errors, ULONG *tcp_connections,
ULONG *tcp_disconnections, ULONG *tcp_connections_dropped,
ULONG *tcp_retransmit_packets);
UINT _nx_tcp_server_socket_accept(NX_TCP_SOCKET *socket_ptr, ULONG wait_option);
UINT _nx_tcp_server_socket_listen(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr, UINT listen_queue_size,
VOID (*tcp_listen_callback)(NX_TCP_SOCKET *socket_ptr, UINT port));
UINT _nx_tcp_server_socket_relisten(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr);
UINT _nx_tcp_server_socket_unaccept(NX_TCP_SOCKET *socket_ptr);
UINT _nx_tcp_server_socket_unlisten(NX_IP *ip_ptr, UINT port);
UINT _nx_tcp_socket_create(NX_IP *ip_ptr, NX_TCP_SOCKET *socket_ptr, CHAR *name,
ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG window_size,
VOID (*tcp_urgent_data_callback)(NX_TCP_SOCKET *socket_ptr),
VOID (*tcp_disconnect_callback)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_delete(NX_TCP_SOCKET *socket_ptr);
UINT _nx_tcp_socket_disconnect(NX_TCP_SOCKET *socket_ptr, ULONG wait_option);
UINT _nx_tcp_socket_info_get(NX_TCP_SOCKET *socket_ptr, ULONG *tcp_packets_sent, ULONG *tcp_bytes_sent,
ULONG *tcp_packets_received, ULONG *tcp_bytes_received,
ULONG *tcp_retransmit_packets, ULONG *tcp_packets_queued,
ULONG *tcp_checksum_errors, ULONG *tcp_socket_state,
ULONG *tcp_transmit_queue_depth, ULONG *tcp_transmit_window,
ULONG *tcp_receive_window);
UINT _nx_tcp_socket_peer_info_get(NX_TCP_SOCKET *socket_ptr, ULONG *peer_ip_address,
ULONG *peer_port);
UINT _nx_tcp_socket_mss_get(NX_TCP_SOCKET *socket_ptr, ULONG *mss);
UINT _nx_tcp_socket_mss_peer_get(NX_TCP_SOCKET *socket_ptr, ULONG *peer_mss);
UINT _nx_tcp_socket_mss_set(NX_TCP_SOCKET *socket_ptr, ULONG mss);
UINT _nx_tcp_socket_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
UINT _nx_tcp_socket_receive_notify(NX_TCP_SOCKET *socket_ptr,
VOID (*tcp_receive_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_window_update_notify_set(NX_TCP_SOCKET *socket_ptr,
VOID (*tcp_windows_update_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_send(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, ULONG wait_option);
UINT _nx_tcp_socket_state_wait(NX_TCP_SOCKET *socket_ptr, UINT desired_state, ULONG wait_option);
UINT _nx_tcp_socket_transmit_configure(NX_TCP_SOCKET *socket_ptr, ULONG max_queue_depth, ULONG timeout,
ULONG max_retries, ULONG timeout_shift);
UINT _nx_tcp_socket_establish_notify(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_establish_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_disconnect_complete_notify(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_disconnect_complete_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_timed_wait_callback(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_timed_wait_callback)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_bytes_available(NX_TCP_SOCKET *, ULONG *);
UINT _nx_tcp_socket_peer_info_get(NX_TCP_SOCKET *, ULONG *, ULONG *);
/* Define TCP component internal function prototypes. */
ULONG _nx_tcp_checksum(NX_PACKET *packet_ptr, ULONG source_address, ULONG destination_address);
VOID _nx_tcp_cleanup_deferred(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_tcp_client_bind_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_tcp_deferred_cleanup_check(NX_IP *ip_ptr);
VOID _nx_tcp_fast_periodic_processing(NX_IP *ip_ptr);
VOID _nx_tcp_fast_periodic_timer_entry(ULONG ip_address);
VOID _nx_tcp_socket_retransmit(NX_IP *ip_ptr, NX_TCP_SOCKET *socket_ptr, UINT need_fast_retransmit);
VOID _nx_tcp_connect_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_tcp_disconnect_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_tcp_initialize(VOID);
UINT _nx_tcp_mss_option_get(UCHAR *option_ptr, ULONG option_area_size, ULONG *mss);
UINT _nx_tcp_window_scaling_option_get(UCHAR *option_ptr, ULONG option_area_size, ULONG *window_scale);
VOID _nx_tcp_no_connection_reset(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_tcp_packet_send_ack(NX_TCP_SOCKET *socket_ptr, ULONG tx_sequence);
VOID _nx_tcp_packet_send_fin(NX_TCP_SOCKET *socket_ptr, ULONG tx_sequence);
VOID _nx_tcp_packet_send_rst(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *header_ptr);
VOID _nx_tcp_packet_send_syn(NX_TCP_SOCKET *socket_ptr, ULONG tx_sequence);
VOID _nx_tcp_periodic_processing(NX_IP *ip_ptr);
VOID _nx_tcp_queue_process(NX_IP *ip_ptr);
VOID _nx_tcp_receive_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_tcp_socket_connection_reset(NX_TCP_SOCKET *socket_ptr);
VOID _nx_tcp_socket_packet_process(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr);
VOID _nx_tcp_socket_receive_queue_flush(NX_TCP_SOCKET *socket_ptr);
VOID _nx_tcp_socket_state_ack_check(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_socket_state_closing(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
UINT _nx_tcp_socket_state_data_check(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr);
VOID _nx_tcp_socket_state_established(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_socket_state_fin_wait1(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_socket_state_fin_wait2(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_socket_state_last_ack(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_socket_state_syn_sent(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_socket_state_syn_received(NX_TCP_SOCKET *socket_ptr, NX_TCP_HEADER *tcp_header_ptr);
VOID _nx_tcp_socket_state_transmit_check(NX_TCP_SOCKET *socket_ptr);
VOID _nx_tcp_socket_thread_resume(TX_THREAD **suspension_list_head, UINT status);
VOID _nx_tcp_socket_thread_suspend(TX_THREAD **suspension_list_head, VOID (*suspend_cleanup)(TX_THREAD *NX_CLEANUP_PARAMETER), NX_TCP_SOCKET *socket_ptr, TX_MUTEX *mutex_ptr, ULONG wait_option);
VOID _nx_tcp_socket_transmit_queue_flush(NX_TCP_SOCKET *socket_ptr);
VOID _nx_tcp_transmit_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
/* Define error checking shells for TCP API services. These are only referenced by the
application. */
UINT _nxe_tcp_client_socket_bind(NX_TCP_SOCKET *socket_ptr, UINT port, ULONG wait_option);
UINT _nxe_tcp_client_socket_connect(NX_TCP_SOCKET *socket_ptr, ULONG server_ip, UINT server_port, ULONG wait_option);
UINT _nxe_tcp_client_socket_port_get(NX_TCP_SOCKET *socket_ptr, UINT *port_ptr);
UINT _nxe_tcp_client_socket_unbind(NX_TCP_SOCKET *socket_ptr);
UINT _nxe_tcp_enable(NX_IP *ip_ptr);
UINT _nxe_tcp_free_port_find(NX_IP *ip_ptr, UINT port, UINT *free_port_ptr);
UINT _nxe_tcp_info_get(NX_IP *ip_ptr, ULONG *tcp_packets_sent, ULONG *tcp_bytes_sent,
ULONG *tcp_packets_received, ULONG *tcp_bytes_received,
ULONG *tcp_invalid_packets, ULONG *tcp_receive_packets_dropped,
ULONG *tcp_checksum_errors, ULONG *tcp_connections,
ULONG *tcp_disconnections, ULONG *tcp_connections_dropped,
ULONG *tcp_retransmit_packets);
UINT _nxe_tcp_server_socket_accept(NX_TCP_SOCKET *socket_ptr, ULONG wait_option);
UINT _nxe_tcp_server_socket_listen(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr, UINT listen_queue_size,
VOID (*tcp_listen_callback)(NX_TCP_SOCKET *socket_ptr, UINT port));
UINT _nxe_tcp_server_socket_relisten(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr);
UINT _nxe_tcp_server_socket_unaccept(NX_TCP_SOCKET *socket_ptr);
UINT _nxe_tcp_server_socket_unlisten(NX_IP *ip_ptr, UINT port);
UINT _nxe_tcp_socket_create(NX_IP *ip_ptr, NX_TCP_SOCKET *socket_ptr, CHAR *name,
ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG window_size,
VOID (*tcp_urgent_data_callback)(NX_TCP_SOCKET *socket_ptr),
VOID (*tcp_disconnect_callback)(NX_TCP_SOCKET *socket_ptr),
UINT tcp_socket_size);
UINT _nxe_tcp_socket_delete(NX_TCP_SOCKET *socket_ptr);
UINT _nxe_tcp_socket_disconnect(NX_TCP_SOCKET *socket_ptr, ULONG wait_option);
UINT _nxe_tcp_socket_info_get(NX_TCP_SOCKET *socket_ptr, ULONG *tcp_packets_sent, ULONG *tcp_bytes_sent,
ULONG *tcp_packets_received, ULONG *tcp_bytes_received,
ULONG *tcp_retransmit_packets, ULONG *tcp_packets_queued,
ULONG *tcp_checksum_errors, ULONG *tcp_socket_state,
ULONG *tcp_transmit_queue_depth, ULONG *tcp_transmit_window,
ULONG *tcp_receive_window);
UINT _nxe_tcp_socket_mss_get(NX_TCP_SOCKET *socket_ptr, ULONG *mss);
UINT _nxe_tcp_socket_mss_peer_get(NX_TCP_SOCKET *socket_ptr, ULONG *peer_mss);
UINT _nxe_tcp_socket_mss_set(NX_TCP_SOCKET *socket_ptr, ULONG mss);
UINT _nxe_tcp_socket_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
UINT _nxe_tcp_socket_receive_notify(NX_TCP_SOCKET *socket_ptr,
VOID (*tcp_receive_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nxe_tcp_socket_window_update_notify_set(NX_TCP_SOCKET *socket_ptr,
VOID (*tcp_windows_update_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nxe_tcp_socket_send(NX_TCP_SOCKET *socket_ptr, NX_PACKET **packet_ptr_ptr, ULONG wait_option);
UINT _nxe_tcp_socket_state_wait(NX_TCP_SOCKET *socket_ptr, UINT desired_state, ULONG wait_option);
UINT _nxe_tcp_socket_transmit_configure(NX_TCP_SOCKET *socket_ptr, ULONG max_queue_depth, ULONG timeout,
ULONG max_retries, ULONG timeout_shift);
UINT _nxe_tcp_socket_bytes_available(NX_TCP_SOCKET *, ULONG *);
UINT _nxe_tcp_socket_peer_info_get(NX_TCP_SOCKET *, ULONG *, ULONG *);
UINT _nxe_tcp_socket_establish_notify(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_establish_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nxe_tcp_socket_disconnect_complete_notify(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_disconnect_complete_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nxe_tcp_socket_timed_wait_callback(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_timed_wait_callback)(NX_TCP_SOCKET *socket_ptr));
/* TCP component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_TCP_INIT
#define TCP_DECLARE
#else
#define TCP_DECLARE extern
#endif
/* Define global data for the TCP component. */
/* Define the actual number of ticks for the fast periodic timer. */
TCP_DECLARE ULONG _nx_tcp_fast_timer_rate;
/* Define the actual number of ticks for the delayed ACK timer. */
TCP_DECLARE ULONG _nx_tcp_ack_timer_rate;
/* Define the actual number of ticks for the retransmit timer. */
TCP_DECLARE ULONG _nx_tcp_transmit_timer_rate;
#endif

167
common/inc/nx_udp.h Normal file
View File

@ -0,0 +1,167 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** User Datagram Protocol (UDP) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_udp.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the NetX User Datagram Protocol (UDP) component, */
/* including all data types and external references. It is assumed */
/* that nx_api.h and nx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_UDP_H
#define NX_UDP_H
/* Define UDP constants. */
#define NX_UDP_ID ((ULONG)0x55445020)
#ifndef NX_UDP_DEBUG_LOG_SIZE
#define NX_UDP_DEBUG_LOG_SIZE 100 /* Maximum size of optional log */
#endif
/* Define Basic UDP packet header data type. This will be used to
build new UDP packets and to examine incoming packets into NetX. */
typedef struct NX_UDP_HEADER_STRUCT
{
/* Define the first 32-bit word of the UDP header. This word contains
the following information:
bits 31-16 UDP 16-bit source port number
bits 15-0 UDP 16-bit destination port number
*/
ULONG nx_udp_header_word_0;
/* Define the second and final word of the UDP header. This word contains
the following information:
bits 31-16 UDP 16-bit UDP length (including 8 header bytes)
bits 15-0 UDP 16-bit checksum (including header and pseudo IP header)
*/
ULONG nx_udp_header_word_1;
} NX_UDP_HEADER;
/* Define UDP component function prototypes. */
UINT _nx_udp_enable(NX_IP *ip_ptr);
UINT _nx_udp_free_port_find(NX_IP *ip_ptr, UINT port, UINT *free_port_ptr);
UINT _nx_udp_info_get(NX_IP *ip_ptr, ULONG *udp_packets_sent, ULONG *udp_bytes_sent,
ULONG *udp_packets_received, ULONG *udp_bytes_received,
ULONG *udp_invalid_packets, ULONG *udp_receive_packets_dropped,
ULONG *udp_checksum_errors);
UINT _nx_udp_socket_bind(NX_UDP_SOCKET *socket_ptr, UINT port, ULONG wait_option);
UINT _nx_udp_socket_checksum_disable(NX_UDP_SOCKET *socket_ptr);
UINT _nx_udp_socket_checksum_enable(NX_UDP_SOCKET *socket_ptr);
UINT _nx_udp_socket_create(NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, CHAR *name,
ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG queue_maximum);
UINT _nx_udp_socket_delete(NX_UDP_SOCKET *socket_ptr);
UINT _nx_udp_socket_info_get(NX_UDP_SOCKET *socket_ptr, ULONG *udp_packets_sent, ULONG *udp_bytes_sent,
ULONG *udp_packets_received, ULONG *udp_bytes_received, ULONG *udp_packets_queued,
ULONG *udp_receive_packets_dropped, ULONG *udp_checksum_errors);
UINT _nx_udp_socket_interface_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, ULONG ip_address, UINT port, UINT interface_index);
UINT _nx_udp_socket_bytes_available(NX_UDP_SOCKET *socket_ptr, ULONG *bytes_available);
UINT _nx_udp_socket_port_get(NX_UDP_SOCKET *socket_ptr, UINT *port_ptr);
UINT _nx_udp_socket_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr,
ULONG wait_option);
UINT _nx_udp_socket_receive_notify(NX_UDP_SOCKET *socket_ptr,
VOID (*udp_receive_notify)(NX_UDP_SOCKET *socket_ptr));
UINT _nx_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
ULONG ip_address, UINT port);
UINT _nx_udp_socket_unbind(NX_UDP_SOCKET *socket_ptr);
UINT _nx_udp_source_extract(NX_PACKET *packet_ptr, ULONG *ip_address, UINT *port);
UINT _nx_udp_packet_info_extract(NX_PACKET *packet_ptr, ULONG *ip_address,
UINT *protocol, UINT *port, UINT *interface_index);
VOID _nx_udp_initialize(VOID);
VOID _nx_udp_bind_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
VOID _nx_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_udp_receive_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
/* Define error checking shells for API services. These are only referenced by the
application. */
UINT _nxe_udp_enable(NX_IP *ip_ptr);
UINT _nxe_udp_free_port_find(NX_IP *ip_ptr, UINT port, UINT *free_port_ptr);
UINT _nxe_udp_info_get(NX_IP *ip_ptr, ULONG *udp_packets_sent, ULONG *udp_bytes_sent,
ULONG *udp_packets_received, ULONG *udp_bytes_received,
ULONG *udp_invalid_packets, ULONG *udp_receive_packets_dropped,
ULONG *udp_checksum_errors);
UINT _nxe_udp_socket_bind(NX_UDP_SOCKET *socket_ptr, UINT port, ULONG wait_option);
UINT _nxe_udp_socket_checksum_disable(NX_UDP_SOCKET *socket_ptr);
UINT _nxe_udp_socket_checksum_enable(NX_UDP_SOCKET *socket_ptr);
UINT _nxe_udp_socket_create(NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, CHAR *name,
ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG queue_maximum, UINT udp_socket_size);
UINT _nxe_udp_socket_delete(NX_UDP_SOCKET *socket_ptr);
UINT _nxe_udp_socket_info_get(NX_UDP_SOCKET *socket_ptr, ULONG *udp_packets_sent, ULONG *udp_bytes_sent,
ULONG *udp_packets_received, ULONG *udp_bytes_received, ULONG *udp_packets_queued,
ULONG *udp_receive_packets_dropped, ULONG *udp_checksum_errors);
UINT _nxe_udp_socket_interface_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr_ptr, ULONG ip_address, UINT port, UINT interface_index);
UINT _nxe_udp_socket_bytes_available(NX_UDP_SOCKET *socket_ptr, ULONG *bytes_available);
UINT _nxe_udp_socket_port_get(NX_UDP_SOCKET *socket_ptr, UINT *port_ptr);
UINT _nxe_udp_socket_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr,
ULONG wait_option);
UINT _nxe_udp_socket_receive_notify(NX_UDP_SOCKET *socket_ptr,
VOID (*udp_receive_notify)(NX_UDP_SOCKET *socket_ptr));
UINT _nxe_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr_ptr,
ULONG ip_address, UINT port);
UINT _nxe_udp_socket_unbind(NX_UDP_SOCKET *socket_ptr);
UINT _nxe_udp_source_extract(NX_PACKET *packet_ptr, ULONG *ip_address, UINT *port);
UINT _nxe_udp_packet_info_extract(NX_PACKET *packet_ptr, ULONG *ip_address,
UINT *protocol, UINT *port, UINT *interface_index);
/* UDP component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef NX_UDP_INIT
#define UDP_DECLARE
#else
#define UDP_DECLARE extern
#endif
#endif

484
common/inc/nx_user_sample.h Normal file
View File

@ -0,0 +1,484 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** User Specific */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* nx_user.h PORTABLE C */
/* 6.0 */
/* */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains user defines for configuring NetX in specific */
/* ways. This file will have an effect only if the application and */
/* NetX library are built with NX_INCLUDE_USER_DEFINE_FILE defined. */
/* Note that all the defines in this file may also be made on the */
/* command line when building NetX library and application objects. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef NX_USER_H
#define NX_USER_H
/* Define various build options for the NetX port. The application should either make changes
here by commenting or un-commenting the conditional compilation defined OR supply the defines
though the compiler's equivalent of the -D option. */
/* Override various options with default values already assigned in nx_api.h or nx_port.h. Please
also refer to nx_port.h for descriptions on each of these options. */
/* Defined, this option bypasses the basic NetX error checking. This define is typically used
after the application is fully debugged. */
/*
#define NX_DISABLE_ERROR_CHECKING
*/
/* Defined, this option enables IP static routing feature. By default IP static routing
feature is not compiled in. */
/*
#define NX_ENABLE_IP_STATIC_ROUTING
*/
/* This define specifies the size of the physical packet header. The default value is 16 (based on
a typical 16-byte Ethernet header). */
/*
#define NX_PHYSICAL_HEADER 16
*/
/* This define specifies the size of the physical packet trailer and is typically used to reserve storage
for things like Ethernet CRCs, etc. */
/*
#define NX_PHYSICAL_TRAILER 4
*/
/* This defines specifies the number of ThreadX timer ticks in one second. The default value is based
on ThreadX timer interrupt. */
/*
#ifdef TX_TIMER_TICKS_PER_SECOND
#define NX_IP_PERIODIC_RATE TX_TIMER_TICKS_PER_SECOND
#else
#define NX_IP_PERIODIC_RATE 100
#endif
*/
/* When defines, ARP reply is sent when address conflict occurs. */
/*
#define NX_ARP_DEFEND_BY_REPLY
*/
/* To use the ARP collision hander to check for invalid ARP messages
matching existing entries in the table (man in the middle attack),
enable this feature. */
/*
#define NX_ENABLE_ARP_MAC_CHANGE_NOTIFICATION
*/
/* This define specifies the number of seconds ARP entries remain valid. The default value of 0 disables
aging of ARP entries. */
/*
#define NX_ARP_EXPIRATION_RATE 0
*/
/* This define specifies the number of seconds between ARP retries. The default value is 10, which represents
10 seconds. */
/*
#define NX_ARP_UPDATE_RATE 10
*/
/* This define specifies how the number of system ticks (NX_IP_PERIODIC_RATE) is divided to calculate the
timer rate for the TCP delayed ACK processing. The default value is 5, which represents 200ms. */
/*
#define NX_TCP_ACK_TIMER_RATE 5
*/
/* This define specifies how the number of system ticks (NX_IP_PERIODIC_RATE) is divided to calculate the
fast TCP timer rate. The fast TCP timer is used to drive various TCP timers, including the delayed ACK
timer. The default value is 10, which represents 100ms. */
/*
#define NX_TCP_FAST_TIMER_RATE 10
*/
/* This define specifies how the number of system ticks (NX_IP_PERIODIC_RATE) is divided to calculate the
timer rate for the TCP transmit retry processing. The default value is 1, which represents 1 second. */
/*
#define NX_TCP_TRANSMIT_TIMER_RATE 1
*/
/* This define specifies how many seconds of inactivity before the keepalive timer activates. The default
value is 7200, which represents 2 hours. */
/*
#define NX_TCP_KEEPALIVE_INITIAL 7200
*/
/* This define specifies how many seconds between retries of the keepalive timer assuming the other side
of the connection is not responding. The default value is 75, which represents 75 seconds between
retries. */
/*
#define NX_TCP_KEEPALIVE_RETRY 75
*/
/* This define specifies the maximum number of ARP retries made without an ARP response. The default
value is 18. */
/*
#define NX_ARP_MAXIMUM_RETRIES 18
*/
/* This defines specifies the maximum number of packets that can be queued while waiting for an ARP
response. The default value is 4. */
/*
#define NX_ARP_MAX_QUEUE_DEPTH 4
*/
/* Defined, this option disables entering ARP request information in the ARP cache. */
/*
#define NX_DISABLE_ARP_AUTO_ENTRY
*/
/* This define specifies the maximum number of multicast groups that can be joined. The default value is
7. */
/*
#define NX_MAX_MULTICAST_GROUPS 7
*/
/* This define specifies the maximum number of TCP server listen requests. The default value is 10. */
/*
#define NX_MAX_LISTEN_REQUESTS 10
*/
/* Defined, this option enables the optional TCP keepalive timer. */
/*
#define NX_ENABLE_TCP_KEEPALIVE
*/
/* Defined, this option enables the TCP window scaling feature. (RFC 1323). Default disabled. */
/*
#define NX_ENABLE_TCP_WINDOW_SCALING
*/
/* Defined, this option enables the optional TCP immediate ACK response processing. */
/*
#define NX_TCP_IMMEDIATE_ACK
*/
/* This define specifies the number of TCP packets to receive before sending an ACK. */
/* The default value is 2: ack every 2 packets. */
/*
#define NX_TCP_ACK_EVERY_N_PACKETS 2
*/
/* Automatically define NX_TCP_ACK_EVERY_N_PACKETS to 1 if NX_TCP_IMMEDIATE_ACK is defined.
This is needed for backward compatibility. */
#if (defined(NX_TCP_IMMEDIATE_ACK) && !defined(NX_TCP_ACK_EVERY_N_PACKETS))
#define NX_TCP_ACK_EVERY_N_PACKETS 1
#endif
/* This define specifies how many transmit retires are allowed before the connection is deemed broken.
The default value is 10. */
/*
#define NX_TCP_MAXIMUM_RETRIES 10
*/
/* This define specifies the maximum depth of the TCP transmit queue before TCP send requests are
suspended or rejected. The default value is 20, which means that a maximum of 20 packets can be in
the transmit queue at any given time. */
/*
#define NX_TCP_MAXIMUM_TX_QUEUE 20
*/
/* This define specifies how the retransmit timeout period changes between successive retries. If this
value is 0, the initial retransmit timeout is the same as subsequent retransmit timeouts. If this
value is 1, each successive retransmit is twice as long. The default value is 0. */
/*
#define NX_TCP_RETRY_SHIFT 0
*/
/* This define specifies how many keepalive retries are allowed before the connection is deemed broken.
The default value is 10. */
/*
#define NX_TCP_KEEPALIVE_RETRIES 10
*/
/* Defined, this option enables deferred driver packet handling. This allows the driver to place a raw
packet on the IP instance and have the driver's real processing routine called from the NetX internal
IP helper thread. */
/*
#define NX_DRIVER_DEFERRED_PROCESSING
*/
/* Defined, this option disables NetX support on the 127.0.0.1 loopback interface.
127.0.0.1 loopback interface is enabled by default. Uncomment out the follow code to disable
the loopback interface. */
/*
#define NX_DISABLE_LOOPBACK_INTERFACE
*/
/* This option defines the number of physical network interfaces to support. Default is one*/
/*
#define NX_MAX_PHYSICAL_INTERFACES 1
*/
/* Defined, this option disables all IP fragmentation logic. */
/*
#define NX_DISABLE_FRAGMENTATION
*/
/* Defined, this option disables checksum logic on received IP packets. This is useful if the link-layer
has reliable checksum or CRC logic. */
/*
#define NX_DISABLE_IP_RX_CHECKSUM
*/
/* Defined, this option disables checksum logic on transmitted IP packets. */
/*
#define NX_DISABLE_IP_TX_CHECKSUM
*/
/* Defined, this option disables checksum logic on received TCP packets. */
/*
#define NX_DISABLE_TCP_RX_CHECKSUM
*/
/* Defined, this option disables checksum logic on transmitted TCP packets. */
/*
#define NX_DISABLE_TCP_TX_CHECKSUM
*/
/* Defined, this option disables checksum logic on received UDP packets. */
/*
#define NX_DISABLE_UDP_RX_CHECKSUM
*/
/* Defined, this option disables checksum logic on transmitted UDP packets. */
/*
#define NX_DISABLE_UDP_TX_CHECKSUM
*/
/* Defined, this option disables checksum logic on received ICMP packets. */
/*
#define NX_DISABLE_ICMP_RX_CHECKSUM
*/
/* Defined, this option disables checksum logic on transmitted ICMP packets. */
/*
#define NX_DISABLE_ICMP_TX_CHECKSUM
*/
/* Defined, this option disables the reset processing during disconnect when the timeout value is
specified as NX_NO_WAIT. */
/*
#define NX_DISABLE_RESET_DISCONNECT
*/
/* Defined, this option disables the addition size checking on received packets. */
/*
#define NX_DISABLE_RX_SIZE_CHECKING
*/
/* Defined, ARP information gathering is disabled. */
/*
#define NX_DISABLE_ARP_INFO
*/
/* Defined, IP information gathering is disabled. */
/*
#define NX_DISABLE_IP_INFO
*/
/* Defined, ICMP information gathering is disabled. */
/*
#define NX_DISABLE_ICMP_INFO
*/
/* Defined, IGMP v2 support is disabled. By default NetX
is built with IGMPv2 enabled . By uncommenting this option,
NetX reverts back to IGMPv1 only. */
/*
#define NX_DISABLE_IGMPV2
*/
/* Defined, IGMP information gathering is disabled. */
/*
#define NX_DISABLE_IGMP_INFO
*/
/* Defined, packet information gathering is disabled. */
/*
#define NX_DISABLE_PACKET_INFO
*/
/* Defined, RARP information gathering is disabled. */
/*
#define NX_DISABLE_RARP_INFO
*/
/* Defined, TCP information gathering is disabled. */
/*
#define NX_DISABLE_TCP_INFO
*/
/* Defined, UDP information gathering is disabled. */
/*
#define NX_DISABLE_UDP_INFO
*/
/* Defined, extended notify support is enabled. This feature adds additional callback/notify services
to NetX API for notifying the host of socket events, such as TCP connection and disconnect
completion. The default is that the extended notify feature is enabled. */
/*
#define NX_ENABLE_EXTENDED_NOTIFY_SUPPORT
*/
/* Defined, NX_PACKET structure is padded for alignment purpose. The default is no padding. */
/*
#define NX_PACKET_HEADER_PAD
#define NX_PACKET_HEADER_PAD_SIZE 1
*/
/* If defined, the incoming SYN packet (connection request) is checked for a minimum acceptable
MSS for the host to accept the connection. The default minimum should be based on the host
application packet pool payload, socket transmit queue depth and relevant application specific parameters.
#define NX_ENABLE_TCP_MSS_CHECKING
#define NX_TCP_MSS_MINIMUM 128
*/
/* Defined, the source address of incoming packet is checked. The default is disabled. */
/*
#define NX_ENABLE_SOURCE_ADDRESS_CHECK
*/
/* Define the ARP defend interval. The default value is 10 seconds. */
/*
#define NX_ARP_DEFEND_INTERVAL 10
*/
/* To limit the number of out of order packets stored to the TCP receive queue and prevent
possible packet pool depletion, define this to a non zero value:
#define NX_TCP_MAX_OUT_OF_ORDER_PACKETS 8
*/
/* Defined, the destination address of ICMP packet is checked. The default is disabled.
An ICMP Echo Request destined to an IP broadcast or IP multicast address will be silently discarded.
*/
/*
#define NX_ENABLE_ICMP_ADDRESS_CHECK
*/
/* Define the max string length. The default value is 1024. */
/*
#define NX_MAX_STRING_LENGTH 1024
*/
#endif

View File

@ -0,0 +1,162 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_announce_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds an ARP Announce packet and calls the associated*/
/* driver to send it out on the specified network interface. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* interface_index IP Interface Index */
/* */
/* OUTPUT */
/* */
/* NX_SUCCESS Successful completion status */
/* NX_NO_PACKET No packet available to send */
/* */
/* CALLS */
/* */
/* _nx_packet_allocate Allocate a packet for the */
/* ARP Announce */
/* [ip_link_driver] User supplied link driver */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_announce_send(NX_IP *ip_ptr, UINT interface_index)
{
NX_INTERFACE *nx_interface;
NX_PACKET *request_ptr;
ULONG *message_ptr;
NX_IP_DRIVER driver_request;
/* Allocate a packet to build the ARP Announce message in. */
if (_nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &request_ptr, (NX_PHYSICAL_HEADER + NX_ARP_MESSAGE_SIZE), NX_NO_WAIT))
{
/* Error getting packet, so just get out! */
return(NX_NO_PACKET);
}
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Set nx_interface. */
nx_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
/* Stamp the packet with the outgoing interface information. */
request_ptr -> nx_packet_ip_interface = nx_interface;
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP requests sent count. */
ip_ptr -> nx_ip_arp_requests_sent++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_REQUEST_SEND, ip_ptr, nx_interface -> nx_interface_ip_address, request_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
/* Build the ARP Announce packet. */
/* Setup the size of the ARP message. */
request_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE;
/* Setup the prepend pointer. */
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)(nx_interface -> nx_interface_physical_address_msw << 16) |
(nx_interface -> nx_interface_physical_address_lsw >> 16);
*(message_ptr + 3) = (ULONG)(nx_interface -> nx_interface_physical_address_lsw << 16) |
(nx_interface -> nx_interface_ip_address >> 16);
*(message_ptr + 4) = (ULONG)(nx_interface -> nx_interface_ip_address << 16);
*(message_ptr + 5) = (ULONG)0;
*(message_ptr + 6) = (ULONG)nx_interface -> nx_interface_ip_address;
/* 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 up the driver request. */
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 = nx_interface;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_ARP_SEND, ip_ptr, request_ptr, request_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
/* Send the ARP Announce packet to the driver. */
(nx_interface -> nx_interface_link_driver_entry)(&driver_request);
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return a successful completion. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,202 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_dynamic_entries_invalidate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function invalidates all ARP dynamic entries currently in */
/* the ARP cache. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* _nx_packet_transmit_release Release queued packet */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_dynamic_entries_invalidate(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_ARP *arp_entry;
NX_ARP *last_arp_entry;
NX_PACKET *packet_ptr;
NX_PACKET *next_packet_ptr;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_DYNAMIC_ENTRIES_INVALIDATE, ip_ptr, ip_ptr -> nx_ip_arp_dynamic_active_count, 0, 0, NX_TRACE_ARP_EVENTS, 0, 0)
/* Obtain protection on this IP instance for access into the ARP dynamic
list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Setup pointers to the starting and ending ARP entries in the dynamic list. */
arp_entry = ip_ptr -> nx_ip_arp_dynamic_list;
if (arp_entry)
{
last_arp_entry = arp_entry -> nx_arp_pool_previous;
}
else
{
last_arp_entry = NX_NULL;
}
/* Walk through the dynamic ARP list until there are no more active entries. */
while ((arp_entry) && (ip_ptr -> nx_ip_arp_dynamic_active_count))
{
/* Yes there is one or more dynamic entries. */
/* Determine if this ARP entry is already active. */
if (arp_entry -> nx_arp_active_list_head)
{
/* Remove this dynamic ARP entry from the associated list. */
/* Disable interrupts. */
TX_DISABLE
/* Determine if this is the only ARP entry on the list. */
if (arp_entry == arp_entry -> nx_arp_active_next)
{
/* Remove the entry from the list. */
*(arp_entry -> nx_arp_active_list_head) = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the list head pointer. */
if (*(arp_entry -> nx_arp_active_list_head) == arp_entry)
{
*(arp_entry -> nx_arp_active_list_head) = arp_entry -> nx_arp_active_next;
}
/* Update the links of the adjacent ARP entries. */
(arp_entry -> nx_arp_active_next) -> nx_arp_active_previous =
arp_entry -> nx_arp_active_previous;
(arp_entry -> nx_arp_active_previous) -> nx_arp_active_next =
arp_entry -> nx_arp_active_next;
}
/* No longer active, clear the active list head. */
arp_entry -> nx_arp_active_list_head = NX_NULL;
/* Decrease the number of active ARP entries. */
ip_ptr -> nx_ip_arp_dynamic_active_count--;
/* Pickup the queued packets head pointer. */
next_packet_ptr = arp_entry -> nx_arp_packets_waiting;
/* Clear the queued packets head pointer. */
arp_entry -> nx_arp_packets_waiting = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Loop to remove all queued packets. */
while (next_packet_ptr)
{
/* Pickup the packet pointer at the head of the queue. */
packet_ptr = next_packet_ptr;
/* Move to the next packet in the queue. */
next_packet_ptr = next_packet_ptr -> nx_packet_queue_next;
/* Clear the next packet queue pointer. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif
/* Release the packet that was queued from the previous ARP entry. */
_nx_packet_transmit_release(packet_ptr);
}
}
/* Determine if we are at the end of the dynamic list. */
if (arp_entry -> nx_arp_pool_next != last_arp_entry)
{
/* No, simply move to the next dynamic entry. */
arp_entry = arp_entry -> nx_arp_pool_next;
}
else
{
/* Yes, we are at the end of the dynamic list, break out of the loop. */
break;
}
}
/* Release the mutex. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return successful status to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,306 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_dynamic_entry_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates an ARP dynamic entry for the application */
/* and assigns the specified IP to hardware mapping. If the specified */
/* hardware address is zero, an actual ARP request will be sent out. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* ip_address IP Address to bind to */
/* physical_msw Physical address MSW */
/* physical_lsw Physical address LSW */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_arp_entry_allocate Allocate an ARP entry */
/* _nx_arp_packet_send Send ARP request */
/* _nx_packet_transmit_release Release ARP queued packet */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* _nx_ip_route_find Find suitable outgoing */
/* interface */
/* (nx_ip_fragment_processing) Fragment processing */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_dynamic_entry_set(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw)
{
TX_INTERRUPT_SAVE_AREA
NX_ARP *arp_ptr;
NX_ARP *search_ptr;
NX_ARP *arp_list_head;
UINT index;
UINT status;
NX_IP_DRIVER driver_request;
NX_PACKET *queued_list_head;
NX_PACKET *packet_ptr;
NX_INTERFACE *nx_interface = NX_NULL;
ULONG next_hop_address = 0;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_DYNAMIC_ENTRY_SET, ip_ptr, ip_address, physical_msw, physical_lsw, NX_TRACE_ARP_EVENTS, 0, 0)
/* Make sure the destination address is directly accessible. */
if ((_nx_ip_route_find(ip_ptr, ip_address, &nx_interface, &next_hop_address) != NX_SUCCESS) ||
(next_hop_address != ip_address))
{
return(NX_IP_ADDRESS_ERROR);
}
/* Obtain protection on this IP instance for access into the ARP dynamic
list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Calculate the hash index for the specified IP address. */
index = (UINT)((ip_address + (ip_address >> 8)) & NX_ROUTE_TABLE_MASK);
/* Pickup the head pointer of the ARP entries for this IP instance. */
arp_list_head = ip_ptr -> nx_ip_arp_table[index];
/* Search the ARP list for the same IP address. */
search_ptr = arp_list_head;
arp_ptr = NX_NULL;
while (search_ptr)
{
/* Determine if there is a duplicate IP address. */
if (search_ptr -> nx_arp_ip_address == ip_address)
{
/* Yes, the IP address matches, setup the ARP entry pointer. */
arp_ptr = search_ptr;
/* Get out of the loop. */
break;
}
/* Move to the next entry in the active list. */
search_ptr = search_ptr -> nx_arp_active_next;
/* Determine if the search pointer is back at the head of
the list. */
if (search_ptr == arp_list_head)
{
/* End of the ARP list, end the search. */
break;
}
}
/* Determine if we didn't find an ARP entry and need to allocate a new
dynamic entry. */
if (arp_ptr == NX_NULL)
{
/* No matching IP address in the ARP cache. */
/* Allocate a dynamic ARP entry. */
status = _nx_arp_entry_allocate(ip_ptr, &(ip_ptr -> nx_ip_arp_table[index]));
/* Determine if an error occurred. */
if (status != NX_SUCCESS)
{
/* Release the mutex. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return the error status. */
return(status);
}
/* Otherwise, setup a pointer to the new ARP entry. The newly allocated
ARP entry was allocated at the end of the ARP list so it should be
referenced using the previous pointer from the list head. */
arp_ptr = (ip_ptr -> nx_ip_arp_table[index]) -> nx_arp_active_previous;
}
/* Setup the IP address and clear the physical mapping. */
arp_ptr -> nx_arp_ip_address = ip_address;
arp_ptr -> nx_arp_physical_address_msw = physical_msw;
arp_ptr -> nx_arp_physical_address_lsw = physical_lsw;
arp_ptr -> nx_arp_retries = 0;
arp_ptr -> nx_arp_entry_next_update = NX_ARP_EXPIRATION_RATE;
arp_ptr -> nx_arp_ip_interface = nx_interface;
/* Determine if a physical address was supplied. */
if ((physical_msw | physical_lsw) == 0)
{
/* Since there isn't physical mapping, change the update rate
for possible ARP retries. */
arp_ptr -> nx_arp_entry_next_update = NX_ARP_UPDATE_RATE;
/* The physical address was not specified so send an
ARP request for the selected IP address. */
_nx_arp_packet_send(ip_ptr, ip_address, nx_interface);
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}
else
{
/* A physical address was supplied. */
/* Initialize the queued list head to NULL. */
queued_list_head = NX_NULL;
/* Determine if this ARP entry has a packet queued up for
sending. */
/* Disable interrupts before checking. */
TX_DISABLE
/* Look at the ARP packet queue pointer. */
if (arp_ptr -> nx_arp_packets_waiting)
{
/* Pickup the packet pointer and clear the ARP queue pointer. */
queued_list_head = arp_ptr -> nx_arp_packets_waiting;
arp_ptr -> nx_arp_packets_waiting = NX_NULL;
}
/* Restore previous interrupt posture. */
TX_RESTORE
/* Are there any packets queued to send? */
while (queued_list_head)
{
/* Pickup the first entry on the list. */
packet_ptr = queued_list_head;
/* Move to the next entry on the ARP packet queue. */
queued_list_head = queued_list_head -> nx_packet_queue_next;
/* Clear the packet's queue next pointer. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
packet_ptr -> nx_packet_ip_interface = nx_interface;
/* Build the driver request packet. */
driver_request.nx_ip_driver_physical_address_msw = physical_msw;
driver_request.nx_ip_driver_physical_address_lsw = physical_lsw;
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_PACKET_SEND;
driver_request.nx_ip_driver_packet = packet_ptr;
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
/* Determine if fragmentation is needed. */
if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_mtu_size)
{
/* Fragmentation is needed, call the fragment routine if available. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Call the IP fragment processing routine. */
(ip_ptr -> nx_ip_fragment_processing)(&driver_request);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif
/* Just release the packet. */
_nx_packet_transmit_release(packet_ptr);
}
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Send the queued IP packet out on the network via the attached driver. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
}
}
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}
}

150
common/src/nx_arp_enable.c Normal file
View File

@ -0,0 +1,150 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enables the ARP management component for the */
/* specified IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* arp_cache_memory Start of ARP cache memory */
/* arp_cache_size Size in bytes of cache memory */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_enable(NX_IP *ip_ptr, VOID *arp_cache_memory, ULONG arp_cache_size)
{
ULONG i;
ULONG arp_entries;
NX_ARP *entry_ptr;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_ENABLE, ip_ptr, arp_cache_memory, arp_cache_size, 0, NX_TRACE_ARP_EVENTS, 0, 0)
/* Clear the entire ARP cache. */
memset((void *)arp_cache_memory, 0, arp_cache_size);
/* Pickup starting address of ARP entry array. */
entry_ptr = (NX_ARP *)arp_cache_memory;
/* Determine how many ARP entries will fit in this cache area. */
arp_entries = arp_cache_size / sizeof(NX_ARP);
/* Setup the list head pointers in the IP instance. At first all ARP
entries are associated with the dynamic ARP list. The static ARP list
is NULL until static ARP entry calls are made. */
ip_ptr -> nx_ip_arp_static_list = NX_NULL;
ip_ptr -> nx_ip_arp_dynamic_list = entry_ptr;
/* Initialize the forward pointers of available ARP entries. */
for (i = 0; i < (arp_entries - 1); i++)
{
/* Setup each entry to point to the next entry. */
entry_ptr -> nx_arp_pool_next = entry_ptr + 1;
entry_ptr++;
}
/* The entry now points to the last entry in the ARP array. Set its
next pointer to the first entry. */
entry_ptr -> nx_arp_pool_next = (NX_ARP *)arp_cache_memory;
/* Initialize the backward pointers of available ARP entries. */
for (i = 0; i < (arp_entries - 1); i++)
{
/* Setup each entry to point to the previous entry. */
entry_ptr -> nx_arp_pool_previous = entry_ptr - 1;
entry_ptr--;
}
/* The entry now points to the first entry, set the previous pointer
to the last entry. */
entry_ptr -> nx_arp_pool_previous = (entry_ptr + (arp_entries - 1));
/* At this point, everything is okay in the ARP enable call.. populate the
information in the IP structure. */
/* Setup the list head pointers in the IP instance. At first all ARP
entries are associated with the dynamic ARP list. The static ARP list
is NULL until static ARP entry calls are made. */
ip_ptr -> nx_ip_arp_static_list = NX_NULL;
ip_ptr -> nx_ip_arp_dynamic_list = (NX_ARP *)arp_cache_memory;
/* Store the initial ARP cache information in the IP control block. */
ip_ptr -> nx_ip_arp_cache_memory = arp_cache_memory;
ip_ptr -> nx_ip_arp_total_entries = arp_entries;
/* Setup the ARP periodic update routine. */
ip_ptr -> nx_ip_arp_periodic_update = _nx_arp_periodic_update;
/* Setup the ARP queue process routine. */
ip_ptr -> nx_ip_arp_queue_process = _nx_arp_queue_process;
/* Setup the ARP send packet routine. */
ip_ptr -> nx_ip_arp_packet_send = _nx_arp_packet_send;
/* Setup the ARP allocate service request pointer. */
ip_ptr -> nx_ip_arp_allocate = _nx_arp_entry_allocate;
/* Return successful completion. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,230 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_entry_allocate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates an ARP entry for a specific new IP */
/* destination. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* arp_list_ptr List head of where to place */
/* the newly allocated ARP */
/* entry */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_packet_transmit_release Release queued packet */
/* */
/* CALLED BY */
/* */
/* NetX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_entry_allocate(NX_IP *ip_ptr, NX_ARP **arp_list_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_ARP *arp_entry;
UINT status;
NX_PACKET *packet_ptr;
NX_PACKET *next_packet_ptr;
/* Determine if there is an ARP entry available in the dynamic list. */
if (ip_ptr -> nx_ip_arp_dynamic_list)
{
/* Yes there are one or more free entries. */
/* Pickup pointer to last used dynamic ARP entry. */
arp_entry = (ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous;
/* Determine if this ARP entry is already active. */
if (arp_entry -> nx_arp_active_list_head)
{
/* Remove this dynamic ARP entry from the associated list. */
/* Disable interrupts. */
TX_DISABLE
/* Determine if this is the only ARP entry on the list. */
if (arp_entry == arp_entry -> nx_arp_active_next)
{
/* Remove the entry from the list. */
*(arp_entry -> nx_arp_active_list_head) = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the list head pointer. */
if (*(arp_entry -> nx_arp_active_list_head) == arp_entry)
{
*(arp_entry -> nx_arp_active_list_head) = arp_entry -> nx_arp_active_next;
}
/* Update the links of the adjacent ARP entries. */
(arp_entry -> nx_arp_active_next) -> nx_arp_active_previous =
arp_entry -> nx_arp_active_previous;
(arp_entry -> nx_arp_active_previous) -> nx_arp_active_next =
arp_entry -> nx_arp_active_next;
}
/* Decrease the number of active ARP entries. */
ip_ptr -> nx_ip_arp_dynamic_active_count--;
/* Pickup the queued packets head pointer. */
next_packet_ptr = arp_entry -> nx_arp_packets_waiting;
/* Clear the queued packets head pointer. */
arp_entry -> nx_arp_packets_waiting = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Loop to remove all queued packets. */
while (next_packet_ptr)
{
/* Pickup the packet pointer at the head of the queue. */
packet_ptr = next_packet_ptr;
/* Move to the next packet in the queue. */
next_packet_ptr = next_packet_ptr -> nx_packet_queue_next;
/* Clear the next packet queue pointer. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif
/* Release the packet that was queued from the previous ARP entry. */
_nx_packet_transmit_release(packet_ptr);
}
}
/* Link the ARP entry at the head of the IP list. */
/* Determine if the ARP entry is being added to an empty list. */
if (*arp_list_ptr)
{
/* Add the ARP entry to the beginning of the nonempty ARP
list. */
arp_entry -> nx_arp_active_list_head = arp_list_ptr;
arp_entry -> nx_arp_active_next = *arp_list_ptr;
arp_entry -> nx_arp_active_previous = (*arp_list_ptr) -> nx_arp_active_previous;
(arp_entry -> nx_arp_active_previous) -> nx_arp_active_next = arp_entry;
(*arp_list_ptr) -> nx_arp_active_previous = arp_entry;
}
else
{
/* Empty list, just put the ARP entry at the beginning. */
arp_entry -> nx_arp_active_list_head = arp_list_ptr;
arp_entry -> nx_arp_active_next = arp_entry;
arp_entry -> nx_arp_active_previous = arp_entry;
/* Now setup the list head. */
*arp_list_ptr = arp_entry;
}
/* Move this ARP entry to the front of the general ARP dynamic entry pool. */
if (arp_entry != ip_ptr -> nx_ip_arp_dynamic_list)
{
/* The current ARP entry is not at the front of the list, so it
must be moved. */
/* Link up the neighbors first. */
(arp_entry -> nx_arp_pool_next) -> nx_arp_pool_previous =
arp_entry -> nx_arp_pool_previous;
(arp_entry -> nx_arp_pool_previous) -> nx_arp_pool_next =
arp_entry -> nx_arp_pool_next;
/* Now link this ARP entry to the head of the list. */
arp_entry -> nx_arp_pool_next = ip_ptr -> nx_ip_arp_dynamic_list;
arp_entry -> nx_arp_pool_previous = (arp_entry -> nx_arp_pool_next) -> nx_arp_pool_previous;
(arp_entry -> nx_arp_pool_previous) -> nx_arp_pool_next = arp_entry;
(arp_entry -> nx_arp_pool_next) -> nx_arp_pool_previous = arp_entry;
/* Now set the list head to this ARP entry. */
ip_ptr -> nx_ip_arp_dynamic_list = arp_entry;
}
/* Increment the number of active dynamic entries. */
ip_ptr -> nx_ip_arp_dynamic_active_count++;
/* Setup a successful status return. */
status = NX_SUCCESS;
}
else
{
/* No more ARP entries are available, all the ARP entries must be
allocated on the static list. */
status = NX_NO_MORE_ENTRIES;
}
/* Return status to the caller. */
return(status);
}

View File

@ -0,0 +1,107 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_gratuitous_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds a Gratuitous ARP packet and calls the */
/* associated driver to send it out on all attached interfaces. */
/* If a response is received at a later time, the supplied response */
/* handler is called. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* response_handler Pointer to function to handle */
/* Gratuitous ARP response */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_arp_announce_send Send ARP announce */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_gratuitous_send(NX_IP *ip_ptr, VOID (*response_handler)(NX_IP *ip_ptr, NX_PACKET *packet_ptr))
{
ULONG i;
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Save the response handler in the IP structure. */
ip_ptr -> nx_ip_arp_gratuitous_response_handler = response_handler;
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
{
/* Skip the entry the IP address is invalid */
if (ip_ptr -> nx_ip_interface[i].nx_interface_ip_address == 0)
{
continue;
}
/* Send ARP announce. */
_nx_arp_announce_send(ip_ptr, i);
}
/* Return a successful completion. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,213 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_hardware_address_find PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function searches for the specified IP address in the ARP */
/* lists. If found, the associated hardware address is returned. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* ip_address IP Address to search for */
/* physical_msw Physical address MSW pointer */
/* physical_lsw Physical address LSW pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_hardware_address_find(NX_IP *ip_ptr, ULONG ip_address,
ULONG *physical_msw, ULONG *physical_lsw)
{
NX_ARP *arp_entry;
ULONG count;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *trace_event;
ULONG trace_timestamp;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_HARDWARE_ADDRESS_FIND, ip_ptr, ip_address, 0, 0, NX_TRACE_ARP_EVENTS, &trace_event, &trace_timestamp)
/* Obtain protection on this IP instance for access into the ARP static
list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Search the static list for a matching IP and hardware mapping. */
arp_entry = ip_ptr -> nx_ip_arp_static_list;
while (arp_entry)
{
/* Determine if we have a match. */
if ((arp_entry -> nx_arp_ip_address == ip_address) &&
(arp_entry -> nx_arp_physical_address_msw | arp_entry -> nx_arp_physical_address_lsw))
{
/* Yes, we have found the ARP entry we are looking for. */
break;
}
else
{
/* Determine if we are at the end of the list. */
if (arp_entry -> nx_arp_pool_next == ip_ptr -> nx_ip_arp_static_list)
{
/* Set the arp_entry to NULL to signify nothing was found and get
out of the search loop. */
arp_entry = NX_NULL;
break;
}
else
{
/* Just move to the next ARP entry on the static list. */
arp_entry = arp_entry -> nx_arp_pool_next;
}
}
}
/* Determine if an entry has been found. If so, we are finished and it needs to be
returned to the caller. */
if (arp_entry)
{
/* Store the hardware address in the return fields. */
*physical_msw = arp_entry -> nx_arp_physical_address_msw;
*physical_lsw = arp_entry -> nx_arp_physical_address_lsw;
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_HARDWARE_ADDRESS_FIND, 0, 0, *physical_msw, *physical_lsw)
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}
/* Otherwise, we need to search the ARP dynamic list for a match. */
arp_entry = ip_ptr -> nx_ip_arp_dynamic_list;
count = 1;
while (arp_entry)
{
/* Determine if we have a match. */
if ((arp_entry -> nx_arp_ip_address == ip_address) &&
(arp_entry -> nx_arp_physical_address_msw | arp_entry -> nx_arp_physical_address_lsw))
{
/* Yes, we have found the ARP entry we are looking for. */
break;
}
else
{
/* Determine if we are at the end of the list of active ARP entries. */
if (count >= ip_ptr -> nx_ip_arp_dynamic_active_count)
{
/* Set the arp_entry to NULL to signify nothing was found and get
out of the search loop. */
arp_entry = NX_NULL;
break;
}
else
{
/* Just move to the next ARP entry on the dynamic list. */
arp_entry = arp_entry -> nx_arp_pool_next;
/* Increment the active count. */
count++;
}
}
}
/* Determine if an entry has been found. If so, we are finished and it needs to be
returned to the caller. */
if (arp_entry)
{
/* Store the hardware address in the return fields. */
*physical_msw = arp_entry -> nx_arp_physical_address_msw;
*physical_lsw = arp_entry -> nx_arp_physical_address_lsw;
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_HARDWARE_ADDRESS_FIND, 0, 0, *physical_msw, *physical_lsw)
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}
else
{
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_ENTRY_NOT_FOUND);
}
}

View File

@ -0,0 +1,170 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function obtains ARP information for the specified IP */
/* instance. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* arp_requests_sent Destination for number of ARP */
/* requests sent */
/* arp_requests_received Destination for number of ARP */
/* requests received */
/* arp_responses_sent Destination for number of ARP */
/* responses sent */
/* arp_responses_received Destination for number of ARP */
/* responses received */
/* arp_dynamic_entries Destination for number of ARP */
/* dynamic entries */
/* arp_static_entries Destination for number of ARP */
/* static entries */
/* arp_aged_entries Destination for number of ARP */
/* aged entries */
/* arp_invalid_messages Destination for number of ARP */
/* invalid messages */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_info_get(NX_IP *ip_ptr, 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)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_INFO_GET, ip_ptr, ip_ptr -> nx_ip_arp_requests_sent, ip_ptr -> nx_ip_arp_responses_received, ip_ptr -> nx_ip_arp_requests_received, NX_TRACE_ARP_EVENTS, 0, 0)
/* Obtain protection on this IP instance. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Determine if ARP requests sent is wanted. */
if (arp_requests_sent)
{
/* Return the number of ARP requests sent by this IP instance. */
*arp_requests_sent = ip_ptr -> nx_ip_arp_requests_sent;
}
/* Determine if ARP requests received is wanted. */
if (arp_requests_received)
{
/* Return the number of ARP requests received by this IP instance. */
*arp_requests_received = ip_ptr -> nx_ip_arp_requests_received;
}
/* Determine if ARP responses sent is wanted. */
if (arp_responses_sent)
{
/* Return the number of ARP responses sent by this IP instance. */
*arp_responses_sent = ip_ptr -> nx_ip_arp_responses_sent;
}
/* Determine if ARP responses received is wanted. */
if (arp_responses_received)
{
/* Return the number of ARP responses received by this IP instance. */
*arp_responses_received = ip_ptr -> nx_ip_arp_responses_received;
}
/* Determine if ARP dynamic entries is wanted. */
if (arp_dynamic_entries)
{
/* Return the number of ARP dynamic entries in this IP instance. */
*arp_dynamic_entries = ip_ptr -> nx_ip_arp_dynamic_active_count;
}
/* Determine if ARP static entries is wanted. */
if (arp_static_entries)
{
/* Return the number of ARP static entries in this IP instance. */
*arp_static_entries = ip_ptr -> nx_ip_arp_static_entries;
}
/* Determine if ARP aged entries is wanted. */
if (arp_aged_entries)
{
/* Return the number of ARP aged entries by this IP instance. */
*arp_aged_entries = ip_ptr -> nx_ip_arp_aged_entries;
}
/* Determine if ARP invalid messages is wanted. */
if (arp_invalid_messages)
{
/* Return the number of ARP invalid messages handled by this IP instance. */
*arp_invalid_messages = ip_ptr -> nx_ip_arp_invalid_messages;
}
/* Release the protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,211 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_ip_address_find PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function searches for the specified hardware address in the */
/* ARP lists. If found, the associated IP address is returned. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* ip_address IP Address return pointer */
/* physical_msw Physical address MSW */
/* physical_lsw Physical address LSW */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_ip_address_find(NX_IP *ip_ptr, ULONG *ip_address,
ULONG physical_msw, ULONG physical_lsw)
{
NX_ARP *arp_entry;
ULONG count;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *trace_event;
ULONG trace_timestamp;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_IP_ADDRESS_FIND, ip_ptr, 0, physical_msw, physical_lsw, NX_TRACE_ARP_EVENTS, &trace_event, &trace_timestamp)
/* Obtain protection on this IP instance for access into the ARP static
list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Search the static list for matching hardware mapping. */
arp_entry = ip_ptr -> nx_ip_arp_static_list;
while (arp_entry)
{
/* Determine if we have a hardware address match. */
if ((arp_entry -> nx_arp_physical_address_msw == physical_msw) &&
(arp_entry -> nx_arp_physical_address_lsw == physical_lsw))
{
/* Yes, we have found the ARP entry we are looking for. */
break;
}
else
{
/* Determine if we are at the end of the list. */
if (arp_entry -> nx_arp_pool_next == ip_ptr -> nx_ip_arp_static_list)
{
/* Set the arp_entry to NULL to signify nothing was found and get
out of the search loop. */
arp_entry = NX_NULL;
break;
}
else
{
/* Just move to the next ARP entry on the static list. */
arp_entry = arp_entry -> nx_arp_pool_next;
}
}
}
/* Determine if an entry has been found. If so, we are finished and it needs to be
returned to the caller. */
if (arp_entry)
{
/* Store the IP address in the return field. */
*ip_address = arp_entry -> nx_arp_ip_address;
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_IP_ADDRESS_FIND, 0, *ip_address, 0, 0)
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}
/* Otherwise, we need to search the ARP dynamic list for a match. */
arp_entry = ip_ptr -> nx_ip_arp_dynamic_list;
count = 1;
while (arp_entry)
{
/* Determine if we have a hardware address match. */
if ((arp_entry -> nx_arp_physical_address_msw == physical_msw) &&
(arp_entry -> nx_arp_physical_address_lsw == physical_lsw))
{
/* Yes, we have found the ARP entry we are looking for. */
break;
}
else
{
/* Determine if we are at the end of the list of active ARP entries. */
if (count >= ip_ptr -> nx_ip_arp_dynamic_active_count)
{
/* Set the arp_entry to NULL to signify nothing was found and get
out of the search loop. */
arp_entry = NX_NULL;
break;
}
else
{
/* Just move to the next ARP entry on the dynamic list. */
arp_entry = arp_entry -> nx_arp_pool_next;
/* Increment the active count. */
count++;
}
}
}
/* Determine if an entry has been found. If so, we are finished and it needs to be
returned to the caller. */
if (arp_entry)
{
/* Store the IP address in the return fields. */
*ip_address = arp_entry -> nx_arp_ip_address;
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_IP_ADDRESS_FIND, 0, *ip_address, 0, 0)
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}
else
{
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_ENTRY_NOT_FOUND);
}
}

View File

@ -0,0 +1,134 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_packet_deferred_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function receives an ARP packet from the link driver (usually */
/* the link driver's input ISR) and places it in the deferred receive */
/* ARP packet queue. This moves the minimal receive ARP packet */
/* processing from the ISR to the IP helper thread. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* tx_event_flags_set Wakeup IP helper thread */
/* */
/* CALLED BY */
/* */
/* Application I/O Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_arp_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Check to see if ARP is enabled on this IP instance. */
if (!ip_ptr -> nx_ip_arp_queue_process)
{
/* ARP is not enabled. */
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP invalid messages count... */
ip_ptr -> nx_ip_arp_invalid_messages++;
#endif
/* Restore interrupts. */
TX_RESTORE
/* Since ARP is not enabled, just release the packet. */
_nx_packet_release(packet_ptr);
/* Return to caller. */
return;
}
/* Check to see if the ARP deferred processing queue is empty. */
if (ip_ptr -> nx_ip_arp_deferred_received_packet_head)
{
/* Not empty, just place the packet at the end of the ARP deferred queue. */
(ip_ptr -> nx_ip_arp_deferred_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
packet_ptr -> nx_packet_queue_next = NX_NULL;
ip_ptr -> nx_ip_arp_deferred_received_packet_tail = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Empty ARP deferred receive processing queue. Just setup the head pointers and
set the event flags to ensure the IP helper thread looks at the ARP deferred
processing queue. */
ip_ptr -> nx_ip_arp_deferred_received_packet_head = packet_ptr;
ip_ptr -> nx_ip_arp_deferred_received_packet_tail = packet_ptr;
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Wakeup IP helper thread to process the ARP deferred receive. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_ARP_REC_EVENT, TX_OR);
}
}

View File

@ -0,0 +1,630 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_packet_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the reception of both the ARP request and */
/* the ARP response. ARP requests are filled in and sent out as ARP */
/* responses. ARP responses received are used to update this IP's */
/* ARP cache and dequeue and send any waiting packet. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* packet_ptr Received ARP packet */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_packet_release Release the ARP request */
/* _nx_packet_transmit_release Release ARP queued packet */
/* (nx_ip_arp_allocate) ARP entry allocate call */
/* (nx_ip_arp_gratuitous_response_handler) ARP gratuitous response */
/* (nx_ip_fragment_processing) Fragment processing */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* _nx_arp_queue_process ARP receive queue processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_arp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
ULONG *message_ptr;
ULONG sender_physical_msw;
ULONG sender_physical_lsw;
ULONG sender_ip;
ULONG target_ip;
UINT message_type;
UINT i;
ULONG index = 0;
UCHAR consumed = NX_FALSE;
NX_ARP *arp_ptr;
NX_IP_DRIVER driver_request;
NX_PACKET *queued_list_head;
NX_INTERFACE *interface_ptr;
#ifndef NX_DISABLE_RX_SIZE_CHECKING
/* Determine if the packet length is valid. */
if (packet_ptr -> nx_packet_length < NX_ARP_MESSAGE_SIZE)
{
/* Invalid ARP message. Release the packet and return. */
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP invalid messages count. */
ip_ptr -> nx_ip_arp_invalid_messages++;
#endif
/* Invalid ARP message. Just release the packet. */
_nx_packet_release(packet_ptr);
/* Return to caller. */
return;
}
#endif /* NX_DISABLE_RX_SIZE_CHECKING */
/* 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);
/* Check packet incoming interface. If the interface filed is not set, stamp it with
the first physical interface. */
if (packet_ptr -> nx_packet_ip_interface == NX_NULL)
{
packet_ptr -> nx_packet_ip_interface = &ip_ptr -> nx_ip_interface[0];
}
interface_ptr = packet_ptr -> nx_packet_ip_interface;
/* Determine if the ARP message type is valid. */
if ((message_type != NX_ARP_OPTION_REQUEST) && (message_type != NX_ARP_OPTION_RESPONSE))
{
/* Invalid ARP message. Release the packet and return. */
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP invalid messages count. */
ip_ptr -> nx_ip_arp_invalid_messages++;
#endif
/* Invalid ARP message. Just release the packet. */
_nx_packet_release(packet_ptr);
/* Return to caller. */
return;
}
/* Pickup 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 = (*(message_ptr + 3) << 16) | (*(message_ptr + 4) >> 16);
target_ip = *(message_ptr + 6);
/* Determine if it is an IP address conflict when IP address probing. */
if ((interface_ptr -> nx_interface_ip_address == 0) &&
(interface_ptr -> nx_interface_ip_probe_address != 0) &&
((sender_ip == interface_ptr -> nx_interface_ip_probe_address) ||
((sender_ip == 0) && (target_ip == interface_ptr -> nx_interface_ip_probe_address))))
{
/* Make sure the sender physical address is not ours. */
if ((sender_physical_msw != interface_ptr -> nx_interface_physical_address_msw) ||
(sender_physical_lsw != interface_ptr -> nx_interface_physical_address_lsw))
{
/* Determine if there is a a IP address conflict notify handler. */
if (interface_ptr -> nx_interface_ip_conflict_notify_handler)
{
/* Find the index number of this interface. */
for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
{
if (interface_ptr == &(ip_ptr -> nx_ip_interface[i]))
{
/* A IP address conflict is present, call the notification handler. */
(interface_ptr -> nx_interface_ip_conflict_notify_handler)(ip_ptr, i, interface_ptr -> nx_interface_ip_probe_address,
sender_physical_msw, sender_physical_lsw);
break;
}
}
}
}
/* Release the packet. */
_nx_packet_release(packet_ptr);
return;
}
/* Determine if it is an address conflict packet after set the IP address. */
if ((sender_ip != 0) && (sender_ip == (packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address)))
{
/* Is it sent from other devices? */
if ((sender_physical_msw != packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_msw) ||
(sender_physical_lsw != packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_lsw))
{
/* Yes it is. */
if (packet_ptr -> nx_packet_ip_interface -> nx_interface_arp_defend_timeout == 0)
{
/* Set defend timeout. */
packet_ptr -> nx_packet_ip_interface -> nx_interface_arp_defend_timeout = NX_ARP_DEFEND_INTERVAL;
/* Send the announcement. */
_nx_arp_packet_send(ip_ptr, sender_ip, packet_ptr -> nx_packet_ip_interface);
}
/* Determine if there is a a IP address conflict notify handler. */
if (interface_ptr -> nx_interface_ip_conflict_notify_handler)
{
/* Find the index number of this interface. */
for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
{
if (interface_ptr == &(ip_ptr -> nx_ip_interface[i]))
{
/* A IP address conflict is present, call the notification handler. */
(interface_ptr -> nx_interface_ip_conflict_notify_handler)(ip_ptr, i, interface_ptr -> nx_interface_ip_probe_address,
sender_physical_msw, sender_physical_lsw);
break;
}
}
}
/* This is likely in response to our previous gratuitous ARP from another entity on the
network has the same IP address. */
/* Determine if there is a gratuitous ARP response handler. */
if (ip_ptr -> nx_ip_arp_gratuitous_response_handler)
{
/* Yes, call the gratuitous ARP response handler. Note that it is responsible
for releasing the packet! */
(ip_ptr -> nx_ip_arp_gratuitous_response_handler)(ip_ptr, packet_ptr);
return;
}
#ifdef NX_ARP_DEFEND_BY_REPLY
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP responses sent count. */
ip_ptr -> nx_ip_arp_responses_sent++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_RESPONSE_SEND, ip_ptr, sender_ip, packet_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Set the ARP message type to ARP response. */
* (message_ptr + 1) = (*(message_ptr + 1) & 0xFFFF0000) | NX_ARP_OPTION_RESPONSE;
/* Now fill in the new source and destination information for the ARP response. */
*(message_ptr + 2) = (ULONG)(packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_msw << 16) |
(packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_lsw >> 16);
*(message_ptr + 3) = (ULONG)(packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_lsw << 16) |
(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address >> 16);
*(message_ptr + 4) = (ULONG)(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address << 16);
*(message_ptr + 5) = (ULONG)0;
*(message_ptr + 6) = (ULONG)0;
/* 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));
/* Make sure the packet length is set properly. */
packet_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE;
/* Setup the append pointer, since the received ARP packet can be padded
with unnecessary bytes. */
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + NX_ARP_MESSAGE_SIZE;
/* Send the ARP request to the driver. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_ARP_RESPONSE_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 = packet_ptr -> nx_packet_ip_interface;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_ARP_RESPONSE_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* No need to update packet_ptr -> nx_packet_ip_interface. When responding to an ARP request, use the same interface where the request was received. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
return;
#endif /* NX_ARP_DEFEND_BY_REPLY */
}
/* Release the conflict packet. */
_nx_packet_release(packet_ptr);
return;
}
/* Determine what type of ARP message this is. Note that ARP requests must
also specify this IP instance's IP address. */
if ((message_type == NX_ARP_OPTION_REQUEST) && (*(message_ptr + 6) == (packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address)))
{
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP requests received count. */
ip_ptr -> nx_ip_arp_requests_received++;
/* Increment the ARP responses sent count. */
ip_ptr -> nx_ip_arp_responses_sent++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_REQUEST_RECEIVE, ip_ptr, sender_ip, packet_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_RESPONSE_SEND, ip_ptr, sender_ip, packet_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Set the ARP message type to ARP response. */
* (message_ptr + 1) = (*(message_ptr + 1) & 0xFFFF0000) | NX_ARP_OPTION_RESPONSE;
/* Now fill in the new source and destination information for the ARP response. */
*(message_ptr + 2) = (ULONG)(packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_msw << 16) |
(packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_lsw >> 16);
*(message_ptr + 3) = (ULONG)(packet_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_lsw << 16) |
(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address >> 16);
*(message_ptr + 4) = (ULONG)(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address << 16) | sender_physical_msw;
*(message_ptr + 5) = (ULONG)sender_physical_lsw;
*(message_ptr + 6) = (ULONG)sender_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 + 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));
/* Make sure the packet length is set properly. */
packet_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE;
/* Setup the append pointer, since the received ARP packet can be padded
with unnecessary bytes. */
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + NX_ARP_MESSAGE_SIZE;
/* Send the ARP request to the driver. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_ARP_RESPONSE_SEND;
driver_request.nx_ip_driver_packet = packet_ptr;
driver_request.nx_ip_driver_physical_address_msw = sender_physical_msw;
driver_request.nx_ip_driver_physical_address_lsw = sender_physical_lsw;
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_ARP_RESPONSE_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* No need to update packet_ptr -> nx_packet_ip_interface. When responding to an ARP request, use the same interface where the request was received. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
/* Set the consumed as NX_TRUE, do not need to release the packet. */
consumed = NX_TRUE;
}
else
{
/* We have a response to a previous ARP request or Gratuitous ARP from another network entity. */
#ifndef NX_DISABLE_ARP_INFO
/* Check for the message type to see which counter to increment. */
if (message_type == NX_ARP_OPTION_REQUEST)
{
/* Increment the ARP requests received count. */
ip_ptr -> nx_ip_arp_requests_received++;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_REQUEST_RECEIVE, ip_ptr, sender_ip, packet_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
}
else
{
/* Increment the ARP responses received count. */
ip_ptr -> nx_ip_arp_responses_received++;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_RESPONSE_RECEIVE, ip_ptr, sender_ip, packet_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
}
#endif
}
/* In either case, search the ARP cache to update any entry that matches the sender's IP
address. */
/* Set the queue list pointer to NULL. */
queued_list_head = NX_NULL;
/* Now we need to search through the active ARP list for the IP address
to see if there is a matching entry. */
/* Ignore anything from any ARP packet with a zero sender IP address. */
if (sender_ip == 0)
{
arp_ptr = NX_NULL;
}
else
{
/* Calculate the hash index for the sender IP address. */
index = (UINT)((sender_ip + (sender_ip >> 8)) & NX_ROUTE_TABLE_MASK);
/* Pickup the first ARP entry. */
arp_ptr = ip_ptr -> nx_ip_arp_table[index];
}
/* Loop to look for an ARP match. */
while (arp_ptr)
{
/* Check for an IP match. */
if (arp_ptr -> nx_arp_ip_address == sender_ip)
{
#ifdef NX_ENABLE_ARP_MAC_CHANGE_NOTIFICATION
/* Determine if there is a ARP collision notify handler. */
if (ip_ptr -> nx_ip_arp_collision_notify_response_handler)
{
/* Now check if the machine address is stored in our ARP cache. */
if ((arp_ptr -> nx_arp_physical_address_msw != 0) || (arp_ptr -> nx_arp_physical_address_lsw != 0))
{
/* Now check if its machine address is different from what is in our ARP cache. */
if ((arp_ptr -> nx_arp_physical_address_msw != sender_physical_msw) ||
(arp_ptr -> nx_arp_physical_address_lsw != sender_physical_lsw))
{
/* A collision is present with the mapping in our ARP table. Call the notification handler.
Note: the application must release the packet. */
(ip_ptr -> nx_ip_arp_collision_notify_response_handler)((void *)packet_ptr);
/* We're done. NetX does not respond or do any further processing.*/
return;
}
}
}
#endif /* NX_ENABLE_ARP_MAC_CHANGE_NOTIFICATION */
/* No need to update the static ARP entry. */
if (arp_ptr -> nx_arp_route_static)
{
break;
}
/* Save the physical address found in this ARP response. */
arp_ptr -> nx_arp_physical_address_msw = sender_physical_msw;
arp_ptr -> nx_arp_physical_address_lsw = sender_physical_lsw;
/* Set the update rate to the expiration rate since we now have an ARP
response. */
arp_ptr -> nx_arp_entry_next_update = NX_ARP_EXPIRATION_RATE;
/* Reset the retry counter for this ARP entry. */
arp_ptr -> nx_arp_retries = 0;
/* Stamp the interface that is attached to this neighbor node. */
arp_ptr -> nx_arp_ip_interface = interface_ptr;
/* Determine if this ARP entry has a packet queued up for
sending. */
/* Disable interrupts before checking. */
TX_DISABLE
/* Look at the ARP packet queue pointer. */
if (arp_ptr -> nx_arp_packets_waiting)
{
/* Pickup the packet pointer and clear the ARP queue pointer. */
queued_list_head = arp_ptr -> nx_arp_packets_waiting;
arp_ptr -> nx_arp_packets_waiting = NX_NULL;
}
/* Restore previous interrupt posture. */
TX_RESTORE
/* Yes, we found a match. Get out of the loop! */
break;
}
/* 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_ptr -> nx_ip_arp_table[index])
{
/* Clear the ARP pointer. */
arp_ptr = NX_NULL;
break;
}
}
/* Determine if we have a packet to release. */
if (consumed == NX_FALSE)
{
_nx_packet_release(packet_ptr);
}
#ifndef NX_DISABLE_ARP_AUTO_ENTRY
/* Determine if anything was found. Ignore ARP messages with a zero IP sender address. */
if ((arp_ptr == NX_NULL) && (sender_ip != 0))
{
/* Calculate the hash index for the sender IP address. */
index = (UINT)((sender_ip + (sender_ip >> 8)) & NX_ROUTE_TABLE_MASK);
/* Allocate a new ARP entry in advance of the need to send to the IP
address. */
if (((ip_ptr -> nx_ip_arp_allocate)(ip_ptr, &(ip_ptr -> nx_ip_arp_table[index]))) == NX_SUCCESS)
{
/* Setup a pointer to the new ARP entry. */
arp_ptr = (ip_ptr -> nx_ip_arp_table[index]) -> nx_arp_active_previous;
/* Setup the IP address and clear the physical mapping. */
arp_ptr -> nx_arp_ip_address = sender_ip;
arp_ptr -> nx_arp_physical_address_msw = sender_physical_msw;
arp_ptr -> nx_arp_physical_address_lsw = sender_physical_lsw;
arp_ptr -> nx_arp_entry_next_update = NX_ARP_EXPIRATION_RATE;
arp_ptr -> nx_arp_retries = 0;
arp_ptr -> nx_arp_ip_interface = interface_ptr;
}
}
#endif /* NX_DISABLE_ARP_AUTO_ENTRY */
/* Are there any packets queued to send? */
while (queued_list_head)
{
/* Pickup the first entry on the list. */
packet_ptr = queued_list_head;
/* Move to the next entry on the ARP packet queue. */
queued_list_head = queued_list_head -> nx_packet_queue_next;
/* Clear the packet's queue next pointer. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Build the driver request packet. */
driver_request.nx_ip_driver_physical_address_msw = sender_physical_msw;
driver_request.nx_ip_driver_physical_address_lsw = sender_physical_lsw;
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_PACKET_SEND;
driver_request.nx_ip_driver_packet = packet_ptr;
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
/* Determine if fragmentation is needed. */
if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_mtu_size)
{
/* Fragmentation is needed, call the fragment routine if available. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Call the IP fragment processing routine. */
(ip_ptr -> nx_ip_fragment_processing)(&driver_request);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif
/* Just release the packet. */
_nx_packet_transmit_release(packet_ptr);
}
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Send the queued IP packet out on the network via the attached driver. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
}
}
}

View File

@ -0,0 +1,152 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_packet_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds an ARP packet and calls the associated driver */
/* to send it out on the network on the specified interface. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* destination_ip Destination IP address */
/* nx_interface Network interface to send */
/* packet out on */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_packet_allocate Allocate a packet for the */
/* ARP request */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* nx_arp_dynamic_entry_set Add dynamic entry to ARP cache*/
/* nx_arp_enable Enable ARP for the IP task */
/* nx_arp_periodic_update Handle periodic ARP tasks */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_arp_packet_send(NX_IP *ip_ptr, ULONG destination_ip, NX_INTERFACE *nx_interface)
{
NX_PACKET *request_ptr;
ULONG *message_ptr;
NX_IP_DRIVER driver_request;
/* 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_ARP_MESSAGE_SIZE), NX_NO_WAIT))
{
/* Error getting packet, so just get out! */
return;
}
/* Stamp the packet with the outgoing interface information. */
request_ptr -> nx_packet_ip_interface = nx_interface;
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP requests sent count. */
ip_ptr -> nx_ip_arp_requests_sent++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_REQUEST_SEND, ip_ptr, destination_ip, request_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Build the ARP request packet. */
/* Setup the size of the ARP message. */
request_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE;
/* Setup the prepend pointer. */
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)(request_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_msw << 16) |
(request_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_lsw >> 16);
*(message_ptr + 3) = (ULONG)(request_ptr -> nx_packet_ip_interface -> nx_interface_physical_address_lsw << 16) |
(request_ptr -> nx_packet_ip_interface -> nx_interface_ip_address >> 16);
*(message_ptr + 4) = (ULONG)(request_ptr -> nx_packet_ip_interface -> nx_interface_ip_address << 16);
*(message_ptr + 5) = (ULONG)0;
*(message_ptr + 6) = (ULONG)destination_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));
/* 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 = nx_interface;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_ARP_SEND, ip_ptr, request_ptr, request_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
(nx_interface -> nx_interface_link_driver_entry) (&driver_request);
}

View File

@ -0,0 +1,273 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_arp.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_periodic_update PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes ARP periodic update requests by walking */
/* through the dynamic ARP list to see if another ARP request needs to */
/* sent. */
/* */
/* INPUT */
/* */
/* ip_address IP address in a ULONG */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_arp_packet_send Send periodic ARP request out */
/* _nx_packet_transmit_release Release queued packet */
/* */
/* CALLED BY */
/* */
/* _nx_ip_thread_entry IP helper thread */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_arp_periodic_update(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
ULONG i;
NX_ARP *arp_entry;
NX_PACKET *packet_ptr;
NX_PACKET *next_packet_ptr;
/* Pickup pointer to ARP dynamic list. */
arp_entry = ip_ptr -> nx_ip_arp_dynamic_list;
/* Loop through the active ARP entries to see if they need updating. */
for (i = 0; i < ip_ptr -> nx_ip_arp_dynamic_active_count; i++)
{
/* Check this ARP entry to see if it need updating. */
if (arp_entry -> nx_arp_entry_next_update)
{
/* Decrement the next update field. */
arp_entry -> nx_arp_entry_next_update--;
/* Determine if an ARP expiration is present. */
if (!arp_entry -> nx_arp_entry_next_update)
{
/* Yes, an ARP expiration is present. */
/* Determine if an ARP expiration is present. */
if (arp_entry -> nx_arp_retries == NX_ARP_MAXIMUM_RETRIES)
{
/* The number of retries has been exceeded. The entry is removed
from the active list and any queued packet is released. */
/* Disable interrupts. */
TX_DISABLE
/* This ARP entry has expired, remove it from the active ARP list. Check to make
sure it is still active. */
if (arp_entry -> nx_arp_active_list_head)
{
/* Determine if this is the only ARP entry on the list. */
if (arp_entry == arp_entry -> nx_arp_active_next)
{
/* Remove the entry from the list. */
*(arp_entry -> nx_arp_active_list_head) = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the list head pointer. */
if (*(arp_entry -> nx_arp_active_list_head) == arp_entry)
{
*(arp_entry -> nx_arp_active_list_head) = arp_entry -> nx_arp_active_next;
}
/* Update the links of the adjacent ARP entries. */
(arp_entry -> nx_arp_active_next) -> nx_arp_active_previous =
arp_entry -> nx_arp_active_previous;
(arp_entry -> nx_arp_active_previous) -> nx_arp_active_next =
arp_entry -> nx_arp_active_next;
}
/* Decrease the number of active ARP entries. */
ip_ptr -> nx_ip_arp_dynamic_active_count--;
/* Clear the active head pointer. */
arp_entry -> nx_arp_active_list_head = NX_NULL;
}
/* Remove from its current position in the dynamic list. */
/* Determine if this is the only ARP entry on the dynamic list. */
if (arp_entry == arp_entry -> nx_arp_pool_next)
{
/* Remove the sole entry from the dynamic list head. */
ip_ptr -> nx_ip_arp_dynamic_list = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the links of the adjacent ARP dynamic pool entries. */
(arp_entry -> nx_arp_pool_next) -> nx_arp_pool_previous =
arp_entry -> nx_arp_pool_previous;
(arp_entry -> nx_arp_pool_previous) -> nx_arp_pool_next =
arp_entry -> nx_arp_pool_next;
/* Update the list head pointer. */
if (ip_ptr -> nx_ip_arp_dynamic_list == arp_entry)
{
ip_ptr -> nx_ip_arp_dynamic_list = arp_entry -> nx_arp_pool_next;
}
}
/* Place the ARP entry at the end of the dynamic ARP pool, which is where new
ARP requests are allocated from. */
/* Determine if the dynamic ARP pool is empty. */
if (ip_ptr -> nx_ip_arp_dynamic_list)
{
/* Dynamic list is not empty, add ARP entry to the end of the list. */
arp_entry -> nx_arp_pool_next =
ip_ptr -> nx_ip_arp_dynamic_list;
arp_entry -> nx_arp_pool_previous =
(ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous;
((ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous) -> nx_arp_pool_next =
arp_entry;
(ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous = arp_entry;
}
else
{
/* Dynamic list was empty, just place it at the head of the dynamic list. */
ip_ptr -> nx_ip_arp_dynamic_list = arp_entry;
arp_entry -> nx_arp_pool_next = arp_entry;
arp_entry -> nx_arp_pool_previous = arp_entry;
}
/* Pickup the queued packets head pointer. */
next_packet_ptr = arp_entry -> nx_arp_packets_waiting;
/* Clear the queued packets head pointer. */
arp_entry -> nx_arp_packets_waiting = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Loop to remove all queued packets. */
while (next_packet_ptr)
{
/* Pickup the packet pointer at the head of the queue. */
packet_ptr = next_packet_ptr;
/* Move to the next packet in the queue. */
next_packet_ptr = next_packet_ptr -> nx_packet_queue_next;
/* Clear the next packet queue pointer. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif
/* Release the packet that was queued for the expired ARP entry. */
_nx_packet_transmit_release(packet_ptr);
}
}
else
{
/* We haven't yet had a response to this ARP request so send it again! */
/* Increment the ARP retry counter. */
arp_entry -> nx_arp_retries++;
/* Setup the ARP update rate to the maximum value again. */
arp_entry -> nx_arp_entry_next_update = NX_ARP_UPDATE_RATE;
/* Send the ARP request out. */
_nx_arp_packet_send(ip_ptr, arp_entry -> nx_arp_ip_address, arp_entry -> nx_arp_ip_interface);
}
}
}
/* Move to the next ARP entry. */
arp_entry = arp_entry -> nx_arp_pool_next;
}
/* Reduce the defend timeout of interfaces. */
for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
{
if (ip_ptr -> nx_ip_interface[i].nx_interface_valid == NX_FALSE)
{
continue;
}
if (ip_ptr -> nx_ip_interface[i].nx_interface_arp_defend_timeout == 0)
{
continue;
}
ip_ptr -> nx_ip_interface[i].nx_interface_arp_defend_timeout--;
}
}

View File

@ -0,0 +1,165 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_probe_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds an ARP Probe packet and calls the associated */
/* driver to send it out on the specified network interface. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* interface_index IP Interface Index */
/* probe_address Probe address */
/* */
/* OUTPUT */
/* */
/* NX_SUCCESS Successful completion status */
/* NX_NO_PACKET No packet available to send */
/* */
/* CALLS */
/* */
/* _nx_packet_allocate Allocate a packet for the */
/* ARP Probe */
/* [ip_link_driver] User supplied link driver */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_probe_send(NX_IP *ip_ptr, UINT interface_index, ULONG probe_address)
{
NX_INTERFACE *nx_interface;
NX_PACKET *request_ptr;
ULONG *message_ptr;
NX_IP_DRIVER driver_request;
/* Allocate a packet to build the ARP Probe message in. */
if (_nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &request_ptr, (NX_PHYSICAL_HEADER + NX_ARP_MESSAGE_SIZE), NX_NO_WAIT))
{
/* Error getting packet, so just get out! */
return(NX_NO_PACKET);
}
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Set nx_interface. */
nx_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
/* Store the probe address. */
nx_interface -> nx_interface_ip_probe_address = probe_address;
/* Stamp the packet with the outgoing interface information. */
request_ptr -> nx_packet_ip_interface = nx_interface;
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP requests sent count. */
ip_ptr -> nx_ip_arp_requests_sent++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ARP_REQUEST_SEND, ip_ptr, probe_address, request_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
/* Build the ARP Probe packet. */
/* Setup the size of the ARP message. */
request_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE;
/* Setup the prepend pointer. */
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)(nx_interface -> nx_interface_physical_address_msw << 16) |
(nx_interface -> nx_interface_physical_address_lsw >> 16);
*(message_ptr + 3) = (ULONG)(nx_interface -> nx_interface_physical_address_lsw << 16);
*(message_ptr + 4) = (ULONG)0;
*(message_ptr + 5) = (ULONG)0;
*(message_ptr + 6) = (ULONG)probe_address;
/* 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 up the driver request. */
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 = nx_interface;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_ARP_SEND, ip_ptr, request_ptr, request_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
/* Send the ARP Probe packet to the driver. */
(nx_interface -> nx_interface_link_driver_entry)(&driver_request);
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return a successful completion. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,108 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_queue_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the received ARP messages on the ARP */
/* queue placed there by nx_arp_deferred_receive. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_arp_packet_receive Process received ARP packet */
/* */
/* CALLED BY */
/* */
/* _nx_ip_thread_entry IP helper thread */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_arp_queue_process(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_PACKET *packet_ptr;
/* Loop to process all ARP deferred packet requests. */
while (ip_ptr -> nx_ip_arp_deferred_received_packet_head)
{
/* Remove the first packet and process it! */
/* Disable interrupts. */
TX_DISABLE
/* Pickup the first packet. */
packet_ptr = ip_ptr -> nx_ip_arp_deferred_received_packet_head;
/* Move the head pointer to the next packet. */
ip_ptr -> nx_ip_arp_deferred_received_packet_head = packet_ptr -> nx_packet_queue_next;
/* Check for end of ARP deferred processing queue. */
if (ip_ptr -> nx_ip_arp_deferred_received_packet_head == NX_NULL)
{
/* Yes, the ARP deferred queue is empty. Set the tail pointer to NULL. */
ip_ptr -> nx_ip_arp_deferred_received_packet_tail = NX_NULL;
}
/* Restore interrupts. */
TX_RESTORE
/* Call the actual ARP packet receive function. */
_nx_arp_packet_receive(ip_ptr, packet_ptr);
}
}

View File

@ -0,0 +1,127 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_static_entries_delete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deletes all ARP static entries currently in */
/* the ARP cache. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* _nx_arp_static_entry_delete Delete a static entry */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_static_entries_delete(NX_IP *ip_ptr)
{
NX_ARP *arp_entry;
UINT status;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *trace_event;
ULONG trace_timestamp;
ULONG deleted_count = 0;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_STATIC_ENTRIES_DELETE, ip_ptr, 0, 0, 0, NX_TRACE_ARP_EVENTS, &trace_event, &trace_timestamp)
/* Obtain protection on this IP instance for access into the ARP static
list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Traverse the static list until it is exhausted. */
do
{
/* Pickup the head of the list. */
arp_entry = ip_ptr -> nx_ip_arp_static_list;
/* Determine if the list is exhausted. */
if (arp_entry == NX_NULL)
{
break;
}
/* Otherwise, delete the static entry delete routine. Note that the delete routine
will modify the list head pointer used above. */
status = _nx_arp_static_entry_delete(ip_ptr, arp_entry -> nx_arp_ip_address,
arp_entry -> nx_arp_physical_address_msw,
arp_entry -> nx_arp_physical_address_lsw);
#ifdef TX_ENABLE_EVENT_TRACE
/* Increment the deleted count. */
deleted_count++;
#endif
} while (status == NX_SUCCESS);
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_ARP_STATIC_ENTRIES_DELETE, 0, deleted_count, 0, 0)
/* Release the mutex. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,309 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_static_entry_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function dynamically allocates an ARP entry for the application*/
/* to make a static IP to hardware mapping. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* ip_address IP Address to bind to */
/* physical_msw Physical address MSW */
/* physical_lsw Physical address LSW */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_packet_transmit_release Release queued packet */
/* _nx_ip_route_find Find suitable outgoing */
/* interface */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_static_entry_create(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw)
{
TX_INTERRUPT_SAVE_AREA
NX_ARP *arp_entry;
NX_ARP **arp_list_ptr;
UINT index;
UINT status;
NX_PACKET *packet_ptr;
NX_PACKET *next_packet_ptr = NX_NULL;
NX_INTERFACE *nx_interface;
ULONG next_hop_address;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_STATIC_ENTRY_CREATE, ip_ptr, ip_address, physical_msw, physical_lsw, NX_TRACE_ARP_EVENTS, 0, 0)
/* Make sure the destination address is directly accessible. */
if ((_nx_ip_route_find(ip_ptr, ip_address, &nx_interface, &next_hop_address) != NX_SUCCESS) ||
(next_hop_address != ip_address))
{
return(NX_IP_ADDRESS_ERROR);
}
/* Obtain protection on this IP instance for access into the ARP dynamic
list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Determine if there is an ARP entry available in the dynamic list. */
if (ip_ptr -> nx_ip_arp_dynamic_list)
{
/* Yes there are one or more free entries. */
#ifndef NX_DISABLE_ARP_INFO
/* Increment the ARP static entry count. */
ip_ptr -> nx_ip_arp_static_entries++;
#endif
/* Disable interrupts. */
TX_DISABLE
/* Pickup pointer to last used dynamic ARP entry, which is also the oldest or least
recently used. */
arp_entry = (ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous;
/* Determine if this ARP entry is already active. */
if (arp_entry -> nx_arp_active_list_head)
{
/* Remove this dynamic ARP entry from the associated list. */
/* Determine if this is the only ARP entry on the list. */
if (arp_entry == arp_entry -> nx_arp_active_next)
{
/* Remove the entry from the list. */
*(arp_entry -> nx_arp_active_list_head) = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the list head pointer. */
if (*(arp_entry -> nx_arp_active_list_head) == arp_entry)
{
*(arp_entry -> nx_arp_active_list_head) = arp_entry -> nx_arp_active_next;
}
/* Update the links of the adjacent ARP entries. */
(arp_entry -> nx_arp_active_next) -> nx_arp_active_previous =
arp_entry -> nx_arp_active_previous;
(arp_entry -> nx_arp_active_previous) -> nx_arp_active_next =
arp_entry -> nx_arp_active_next;
}
/* Decrease the number of active ARP entries. */
ip_ptr -> nx_ip_arp_dynamic_active_count--;
/* Pickup the queued packets head pointer. */
next_packet_ptr = arp_entry -> nx_arp_packets_waiting;
/* Clear the queued packets head pointer. */
arp_entry -> nx_arp_packets_waiting = NX_NULL;
}
/* Remove this entry from the ARP dynamic list. */
/* Determine if this is the only ARP entry on the dynamic list. */
if (arp_entry == arp_entry -> nx_arp_pool_next)
{
/* Remove the sole entry from the dynamic list head. */
ip_ptr -> nx_ip_arp_dynamic_list = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the links of the adjacent ARP dynamic pool entries. */
(arp_entry -> nx_arp_pool_next) -> nx_arp_pool_previous =
arp_entry -> nx_arp_pool_previous;
(arp_entry -> nx_arp_pool_previous) -> nx_arp_pool_next =
arp_entry -> nx_arp_pool_next;
/* Update the list head pointer. */
if (ip_ptr -> nx_ip_arp_dynamic_list == arp_entry)
{
ip_ptr -> nx_ip_arp_dynamic_list = arp_entry -> nx_arp_pool_next;
}
}
/* Restore interrupts briefly. */
TX_RESTORE
/* Loop to remove all queued packets. */
while (next_packet_ptr)
{
/* Pickup the packet pointer at the head of the queue. */
packet_ptr = next_packet_ptr;
/* Move to the next packet in the queue. */
next_packet_ptr = next_packet_ptr -> nx_packet_queue_next;
/* Clear the next packet queue pointer. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif
/* Release the packet that was queued from the removed ARP entry. */
_nx_packet_transmit_release(packet_ptr);
}
/* Calculate the hash index for the IP address. */
index = (UINT)((ip_address + (ip_address >> 8)) & NX_ROUTE_TABLE_MASK);
/* Indicate the entry does not need updating. */
arp_entry -> nx_arp_entry_next_update = 0;
/* Place the important information in the ARP structure. */
arp_entry -> nx_arp_route_static = NX_TRUE;
arp_entry -> nx_arp_ip_address = ip_address;
arp_entry -> nx_arp_physical_address_msw = physical_msw;
arp_entry -> nx_arp_physical_address_lsw = physical_lsw;
arp_entry -> nx_arp_ip_interface = nx_interface;
/* Setup the active ARP list head. */
arp_list_ptr = &(ip_ptr -> nx_ip_arp_table[index]);
/* Disable interrupts. */
TX_DISABLE
/* Add the entry to the ARP static list. */
/* Determine if the ARP static list is empty. */
if (ip_ptr -> nx_ip_arp_static_list == NX_NULL)
{
/* Just place this single ARP entry on the list. */
arp_entry -> nx_arp_pool_next = arp_entry;
arp_entry -> nx_arp_pool_previous = arp_entry;
ip_ptr -> nx_ip_arp_static_list = arp_entry;
}
else
{
/* Add to the end of the ARP static list. */
arp_entry -> nx_arp_pool_next =
ip_ptr -> nx_ip_arp_static_list;
arp_entry -> nx_arp_pool_previous =
(ip_ptr -> nx_ip_arp_static_list) -> nx_arp_pool_previous;
((ip_ptr -> nx_ip_arp_static_list) -> nx_arp_pool_previous) -> nx_arp_pool_next =
arp_entry;
(ip_ptr -> nx_ip_arp_static_list) -> nx_arp_pool_previous = arp_entry;
}
/* Link the ARP entry at the head of the active ARP list. */
/* Determine if the ARP entry is being added to an empty list. */
if (*arp_list_ptr)
{
/* Add the ARP entry to the beginning of the nonempty ARP
list. */
arp_entry -> nx_arp_active_list_head = arp_list_ptr;
arp_entry -> nx_arp_active_next = *arp_list_ptr;
arp_entry -> nx_arp_active_previous = (*arp_list_ptr) -> nx_arp_active_previous;
(arp_entry -> nx_arp_active_previous) -> nx_arp_active_next = arp_entry;
(*arp_list_ptr) -> nx_arp_active_previous = arp_entry;
}
else
{
/* Empty list, just put the ARP entry at the beginning. */
arp_entry -> nx_arp_active_list_head = arp_list_ptr;
arp_entry -> nx_arp_active_next = arp_entry;
arp_entry -> nx_arp_active_previous = arp_entry;
/* Now setup the list head. */
*arp_list_ptr = arp_entry;
}
/* Restore interrupts. */
TX_RESTORE
/* Setup a successful status return. */
status = NX_SUCCESS;
}
else
{
/* No more ARP entries are available, all the ARP entries must be
allocated on the static list. */
status = NX_NO_MORE_ENTRIES;
}
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(status);
}

View File

@ -0,0 +1,259 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Address Resolution Protocol (ARP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_arp_static_entry_delete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function removes a previously setup static IP to hardware */
/* mapping and returns the associated ARP entry back to the dynamic */
/* ARP pool. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* ip_address IP Address binding to delete */
/* physical_msw Physical address MSW */
/* physical_lsw Physical address LSW */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* _nx_arp_static_entries_delete Delete all static entries */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_arp_static_entry_delete(NX_IP *ip_ptr, ULONG ip_address,
ULONG physical_msw, ULONG physical_lsw)
{
TX_INTERRUPT_SAVE_AREA
NX_ARP *arp_entry;
UINT status;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ARP_STATIC_ENTRY_DELETE, ip_ptr, ip_address, physical_msw, physical_lsw, NX_TRACE_ARP_EVENTS, 0, 0)
/* Obtain protection on this IP instance for access into the ARP static
list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Search the static list for a matching IP and hardware mapping. */
arp_entry = ip_ptr -> nx_ip_arp_static_list;
while (arp_entry)
{
/* Determine if we have a match. */
if ((arp_entry -> nx_arp_ip_address == ip_address) &&
(arp_entry -> nx_arp_physical_address_msw == physical_msw) &&
(arp_entry -> nx_arp_physical_address_lsw == physical_lsw))
{
/* Yes, we have found the ARP entry we are looking for. */
break;
}
else
{
/* Determine if we are at the end of the list. */
if (arp_entry -> nx_arp_pool_next == ip_ptr -> nx_ip_arp_static_list)
{
/* Set the arp_entry to NULL to signify nothing was found and get
out of the search loop. */
arp_entry = NX_NULL;
break;
}
else
{
/* Just move to the next ARP entry on the static list. */
arp_entry = arp_entry -> nx_arp_pool_next;
}
}
}
/* At this point the ARP entry pointer determines whether or not anything was found
on the static list. */
if (arp_entry)
{
/* The static entry was found. It needs to be unlinked from the active
list and the static list and re-linked to the end of the dynamic list. */
#ifndef NX_DISABLE_ARP_INFO
/* Decrement the ARP static entry count. */
ip_ptr -> nx_ip_arp_static_entries--;
#endif
/* Disable interrupts temporarily. */
TX_DISABLE
/* Determine if this ARP entry is already active. */
if (arp_entry -> nx_arp_active_list_head)
{
/* Remove this dynamic ARP entry from the associated list. */
/* Determine if this is the only ARP entry on the list. */
if (arp_entry == arp_entry -> nx_arp_active_next)
{
/* Remove the entry from the list. */
*(arp_entry -> nx_arp_active_list_head) = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the list head pointer. */
if (*(arp_entry -> nx_arp_active_list_head) == arp_entry)
{
*(arp_entry -> nx_arp_active_list_head) = arp_entry -> nx_arp_active_next;
}
/* Update the links of the adjacent ARP entries. */
(arp_entry -> nx_arp_active_next) -> nx_arp_active_previous =
arp_entry -> nx_arp_active_previous;
(arp_entry -> nx_arp_active_previous) -> nx_arp_active_next =
arp_entry -> nx_arp_active_next;
}
}
/* Remove this entry from the static ARP list. */
/* Determine if this is the only ARP entry on the static list. */
if (arp_entry == arp_entry -> nx_arp_pool_next)
{
/* Remove the sole entry from the static list head. */
ip_ptr -> nx_ip_arp_static_list = NX_NULL;
}
else
{
/* Remove the entry from a list of more than one entry. */
/* Update the links of the adjacent ARP dynamic pool entries. */
(arp_entry -> nx_arp_pool_next) -> nx_arp_pool_previous =
arp_entry -> nx_arp_pool_previous;
(arp_entry -> nx_arp_pool_previous) -> nx_arp_pool_next =
arp_entry -> nx_arp_pool_next;
/* Update the list head pointer. */
if (ip_ptr -> nx_ip_arp_static_list == arp_entry)
{
ip_ptr -> nx_ip_arp_static_list = arp_entry -> nx_arp_pool_next;
}
}
/* Restore interrupts briefly. */
TX_RESTORE
/* Clear the fields that indicate the ARP entry is a static entry and make sure
it is viewed as inactive in preparation for returning it to the dynamic ARP
pool. */
arp_entry -> nx_arp_route_static = NX_FALSE;
arp_entry -> nx_arp_active_list_head = NX_NULL;
/* Disable interrupts again. */
TX_DISABLE
/* Place the ARP entry at the end of the dynamic ARP pool, which is where new
ARP requests are allocated from. */
/* Determine if the dynamic ARP pool is empty. */
if (ip_ptr -> nx_ip_arp_dynamic_list)
{
/* Dynamic list is not empty, add former static ARP entry to the end of the list. */
arp_entry -> nx_arp_pool_next =
ip_ptr -> nx_ip_arp_dynamic_list;
arp_entry -> nx_arp_pool_previous =
(ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous;
((ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous) -> nx_arp_pool_next =
arp_entry;
(ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous = arp_entry;
}
else
{
/* Dynamic list was empty, just place it at the head of the dynamic list. */
ip_ptr -> nx_ip_arp_dynamic_list = arp_entry;
arp_entry -> nx_arp_pool_next = arp_entry;
arp_entry -> nx_arp_pool_previous = arp_entry;
}
/* Restore interrupts. */
TX_RESTORE
/* Setup the return status. */
status = NX_SUCCESS;
}
else
{
/* Indicate the entry was not found. */
status = NX_ENTRY_NOT_FOUND;
}
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return status to the caller. */
return(status);
}

View File

@ -0,0 +1,182 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_icmp.h"
#if (!defined(NX_DISABLE_ICMP_TX_CHECKSUM) || !defined(NX_DISABLE_ICMP_RX_CHECKSUM))
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_checksum_compute PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function computes the ICMP checksum from the supplied packet */
/* pointer. */
/* */
/* INPUT */
/* */
/* packet_ptr Pointer to packet */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ICMP routines */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
ULONG _nx_icmp_checksum_compute(NX_PACKET *packet_ptr)
{
ULONG checksum = 0;
ULONG long_temp;
USHORT short_temp;
ULONG length;
UCHAR *word_ptr;
NX_PACKET *current_packet;
/* Setup the length of the packet checksum. */
length = packet_ptr -> nx_packet_length;
/* Determine if we need to add a padding byte. */
if (((length / sizeof(USHORT)) * sizeof(USHORT)) != length)
{
/* We have single byte alignment and we need two byte alignment. */
length++;
/* Determine if there is a last packet pointer. */
if (packet_ptr -> nx_packet_last)
{
/* Multi-packet message, add a zero byte at the end. */
*((packet_ptr -> nx_packet_last) -> nx_packet_append_ptr) = 0;
}
else
{
/* Write a zero byte at the end of the first and only packet. */
*(packet_ptr -> nx_packet_append_ptr) = 0;
}
}
/* 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;
/* 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);
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the ICMP word. */
NX_CHANGE_ULONG_ENDIAN(long_temp);
/* Add upper 16-bits into checksum. */
checksum = checksum + (long_temp >> NX_SHIFT_BY_16);
/* Add lower 16-bits into checksum. */
checksum = checksum + (long_temp & NX_LOWER_16_MASK);
/* 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);
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the ICMP word. */
NX_CHANGE_USHORT_ENDIAN(short_temp);
/* Add next 16-bit word into checksum. */
checksum = checksum + short_temp;
/* 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;
}
}
/* 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);
/* Mask off the upper 16-bits. */
checksum = checksum & NX_LOWER_16_MASK;
/* Return the computed checksum. */
return(checksum);
}
#endif

View File

@ -0,0 +1,168 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_icmp.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_cleanup PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes ICMP ping timeout and thread terminate */
/* actions that require the IP/ICMP data structures to be cleaned */
/* up. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to suspended thread's */
/* control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_system_resume Resume thread service */
/* */
/* CALLED BY */
/* */
/* _nx_ip_delete Delete IP instance */
/* _tx_thread_timeout Thread timeout processing */
/* _tx_thread_terminate Thread terminate processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_icmp_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER)
{
TX_INTERRUPT_SAVE_AREA
NX_IP *ip_ptr;
NX_CLEANUP_EXTENSION
/* Setup pointer to IP control block. */
ip_ptr = (NX_IP *)thread_ptr -> tx_thread_suspend_control_block;
/* Disable interrupts to remove the suspended thread from the packet pool. */
TX_DISABLE
/* Determine if the cleanup is still required. */
if ((thread_ptr -> tx_thread_suspend_cleanup) && (ip_ptr) &&
(ip_ptr -> nx_ip_id == NX_IP_ID))
{
/* Yes, we still have thread suspension! */
/* Clear the suspension cleanup flag. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Remove the suspended thread from the list. */
/* See if this is the only suspended thread on the list. */
if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
ip_ptr -> nx_ip_icmp_ping_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same suspension list. */
/* Update the list head pointer. */
if (ip_ptr -> nx_ip_icmp_ping_suspension_list == thread_ptr)
{
ip_ptr -> nx_ip_icmp_ping_suspension_list = thread_ptr -> tx_thread_suspended_next;
}
/* Update the links of the adjacent threads. */
(thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
thread_ptr -> tx_thread_suspended_previous;
(thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
thread_ptr -> tx_thread_suspended_next;
}
/* Decrement the suspension count. */
ip_ptr -> nx_ip_icmp_ping_suspended_count--;
/* Now we need to determine if this cleanup is from a terminate, timeout,
or from a wait abort. */
if (thread_ptr -> tx_thread_state == TX_TCP_IP)
{
/* Thread still suspended on the IP ping message. Setup return error status and
resume the thread. */
/* Setup return status. */
thread_ptr -> tx_thread_suspend_status = NX_NO_RESPONSE;
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP timeout count. */
ip_ptr -> nx_ip_ping_timeouts++;
#endif
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread! Check for preemption even though we are executing
from the system timer thread right now which normally executes at the
highest priority. */
_tx_thread_system_resume(thread_ptr);
/* Finished, just return. */
return;
}
}
/* Restore interrupts. */
TX_RESTORE
}

View File

@ -0,0 +1,85 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_icmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enables the ICMP management component for the */
/* specified IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_icmp_enable(NX_IP *ip_ptr)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ICMP_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_ICMP_EVENTS, 0, 0)
/* Setup the ICMP packet queue processing routine. */
ip_ptr -> nx_ip_icmp_queue_process = _nx_icmp_queue_process;
/* Setup the ICMP packet receiving routine, thereby enabling ICMP traffic. */
ip_ptr -> nx_ip_icmp_packet_receive = _nx_icmp_packet_receive;
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,149 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_icmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves the selected ICMP information for the */
/* caller. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* pings_sent Destination for number of */
/* pings sent */
/* ping_timeouts Destination for number of */
/* ping timeouts */
/* ping_threads_suspended Destination for number of */
/* threads suspended on pings */
/* ping_responses_received Destination for number of */
/* ping responses received */
/* icmp_checksum_errors Destination for number of */
/* ICMP checksum errors */
/* icmp_unhandled_messages Destination for number of */
/* unhandled ICMP messages */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_icmp_info_get(NX_IP *ip_ptr, ULONG *pings_sent, ULONG *ping_timeouts,
ULONG *ping_threads_suspended, ULONG *ping_responses_received,
ULONG *icmp_checksum_errors, ULONG *icmp_unhandled_messages)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ICMP_INFO_GET, ip_ptr, ip_ptr -> nx_ip_pings_sent, ip_ptr -> nx_ip_ping_responses_received, ip_ptr -> nx_ip_pings_received, NX_TRACE_ICMP_EVENTS, 0, 0)
/* Obtain protection on this IP instance. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Determine if pings sent is wanted. */
if (pings_sent)
{
/* Return the number of pings sent by this IP instance. */
*pings_sent = ip_ptr -> nx_ip_pings_sent;
}
/* Determine if ping timeouts is wanted. */
if (ping_timeouts)
{
/* Return the number of ping timeouts by this IP instance. */
*ping_timeouts = ip_ptr -> nx_ip_ping_timeouts;
}
/* Determine if ping threads suspended is wanted. */
if (ping_threads_suspended)
{
/* Return the number of ping threads suspended by this IP instance. */
*ping_threads_suspended = ip_ptr -> nx_ip_ping_threads_suspended;
}
/* Determine if ping responses received is wanted. */
if (ping_responses_received)
{
/* Return the number of ping responses received by this IP instance. */
*ping_responses_received = ip_ptr -> nx_ip_ping_responses_received;
}
/* Determine if ICMP checksum errors is wanted. */
if (icmp_checksum_errors)
{
/* Return the number of ICMP checksum errors detected by this IP instance. */
*icmp_checksum_errors = ip_ptr -> nx_ip_icmp_checksum_errors;
}
/* Determine if ICMP unhandled messages is wanted. */
if (icmp_unhandled_messages)
{
/* Return the number of ICMP unhandled messages by this IP instance. */
*icmp_unhandled_messages = ip_ptr -> nx_ip_icmp_unhandled_messages;
}
/* Release protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return a successful status. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,340 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_packet.h"
#include "nx_ip.h"
#include "nx_icmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_packet_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the ICMP received packet and lifts any */
/* associated threads suspended on it. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr ICMP packet pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_icmp_checksum_compute Computer ICMP checksum */
/* _nx_ip_packet_send Send ICMP packet out */
/* _nx_packet_release Packet release function */
/* _tx_thread_system_resume Resume suspended thread */
/* _tx_thread_system_preempt_check Check for preemption */
/* */
/* CALLED BY */
/* */
/* _nx_icmp_packet_receive ICMP packet receive */
/* _nx_icmp_queue_process ICMP packet queue processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_icmp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_ICMP_HEADER *header_ptr;
TX_THREAD *thread_ptr;
ULONG suspended;
ULONG *message_ptr;
ULONG message_type;
ULONG sequence_num;
#if (!defined(NX_DISABLE_ICMP_TX_CHECKSUM) || !defined(NX_DISABLE_ICMP_RX_CHECKSUM))
ULONG checksum;
#endif
/* Point to the ICMP message header. */
header_ptr = (NX_ICMP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
#ifndef NX_DISABLE_ICMP_RX_CHECKSUM
/* Calculate the ICMP message checksum. */
checksum = _nx_icmp_checksum_compute(packet_ptr);
checksum = ~checksum & NX_LOWER_16_MASK;
/* Determine if the checksum is valid. */
if (checksum)
{
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP invalid packet error. */
ip_ptr -> nx_ip_icmp_invalid_packets++;
/* Increment the ICMP checksum error count. */
ip_ptr -> nx_ip_icmp_checksum_errors++;
#endif
/* Nope, the checksum is invalid. Toss this ICMP packet out. */
_nx_packet_release(packet_ptr);
return;
}
#endif
/* If NX_LITTLE_ENDIAN is defined, the header needs to be swapped
so we can examine the ICMP message type. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0);
/* Pickup the ICMP message type. */
message_type = (header_ptr -> nx_icmp_header_word_0) >> 24;
/* Is the message an Echo Reply? */
if (message_type == NX_ICMP_ECHO_REPLY_TYPE)
{
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP responses received count. */
ip_ptr -> nx_ip_ping_responses_received++;
#endif
/* If NX_LITTLE_ENDIAN is defined, the second word of the header
needs to be swapped back so we can examine the ICMP sequence number. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_1);
/* Pickup sequence number. */
sequence_num = (header_ptr -> nx_icmp_header_word_1) & NX_LOWER_16_MASK;
/* Disable interrupts. */
TX_DISABLE
/* Pickup the head pointer and the suspended count. */
thread_ptr = ip_ptr -> nx_ip_icmp_ping_suspension_list;
suspended = ip_ptr -> nx_ip_icmp_ping_suspended_count;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Search through the suspended threads waiting for a ECHO (ping) response
in an attempt to find a matching sequence number. */
while (suspended--)
{
/* Determine if the sequence number matches a suspended thread. */
if (thread_ptr -> tx_thread_suspend_info == sequence_num)
{
/* Disable interrupts. */
TX_DISABLE
/* See if this is the only suspended thread on the list. */
if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
ip_ptr -> nx_ip_icmp_ping_suspension_list = NX_NULL;
}
else
{
/* At least one more thread is on the same expiration list. */
/* Update the list head pointer. */
if (ip_ptr -> nx_ip_icmp_ping_suspension_list == thread_ptr)
{
ip_ptr -> nx_ip_icmp_ping_suspension_list = thread_ptr -> tx_thread_suspended_next;
}
/* Update the links of the adjacent threads. */
(thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
thread_ptr -> tx_thread_suspended_previous;
(thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
thread_ptr -> tx_thread_suspended_next;
}
/* Decrement the suspension count. */
ip_ptr -> nx_ip_icmp_ping_suspended_count--;
/* Prepare for resumption of the first thread. */
/* Clear cleanup routine to avoid timeout. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Adjust this packet to remove the ICMP header that is still in front of
the response message. */
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - sizeof(NX_ICMP_HEADER);
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_ICMP_HEADER);
/* Return this block pointer to the suspended thread waiting for
a block. */
*((NX_PACKET **)thread_ptr -> tx_thread_additional_suspend_info) = packet_ptr;
/* Clear packet pointer so we don't try to release it below. */
packet_ptr = NX_NULL;
/* Put return status into the thread control block. */
thread_ptr -> tx_thread_suspend_status = NX_SUCCESS;
/* Resume thread. */
_tx_thread_system_resume(thread_ptr);
/* Get out of the loop. */
break;
}
else
{
/* Just move to the next suspended thread. */
thread_ptr = thread_ptr -> tx_thread_suspended_next;
}
}
/* Determine if no match was made and we just have to release the packet. */
if (packet_ptr)
{
/* Yes, just release the packet. */
_nx_packet_release(packet_ptr);
}
/* Disable interrupts. */
TX_DISABLE
/* Release preemption disable. */
_tx_thread_preempt_disable--;
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
}
else if (message_type == NX_ICMP_ECHO_REQUEST_TYPE)
{
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP pings received count. */
ip_ptr -> nx_ip_pings_received++;
#endif
/* Change the type to Echo Reply and send back the message to the caller. */
header_ptr -> nx_icmp_header_word_0 = NX_ICMP_ECHO_REPLY_TYPE << 24;
#ifndef NX_DISABLE_ICMP_TX_CHECKSUM
/* If NX_LITTLE_ENDIAN is defined, the header need to be swapped back
to match the data area. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0);
/* Compute the checksum of the Echo Reply. */
checksum = _nx_icmp_checksum_compute(packet_ptr);
/* If NX_LITTLE_ENDIAN is defined, the header need to be swapped back
so we insert the checksum. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0);
/* Store the checksum. */
header_ptr -> nx_icmp_header_word_0 = header_ptr -> nx_icmp_header_word_0 | (~checksum & NX_LOWER_16_MASK);
#endif
/* If NX_LITTLE_ENDIAN is defined, the header need to be swapped back
for output. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0);
/* Pickup the return IP address. */
message_ptr = (ULONG *)packet_ptr -> nx_packet_prepend_ptr;
/* Figure out the best interface to send the ICMP packet on. */
if (_nx_ip_route_find(ip_ptr, *(message_ptr - 2), &packet_ptr -> nx_packet_ip_interface,
&packet_ptr -> nx_packet_next_hop_address) != NX_SUCCESS)
{
/* Not a valid interface available. */
_nx_packet_release(packet_ptr);
return;
}
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ICMP_RECEIVE, ip_ptr, *(message_ptr - 2), packet_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP pings responded to count. */
ip_ptr -> nx_ip_pings_responded_to++;
#endif
/* Send the ICMP packet to the IP component. */
_nx_ip_packet_send(ip_ptr, packet_ptr, *(message_ptr - 2),
NX_IP_NORMAL, NX_IP_TIME_TO_LIVE, NX_IP_ICMP, NX_FRAGMENT_OKAY);
}
else
{
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP unhandled message count. */
ip_ptr -> nx_ip_icmp_unhandled_messages++;
#endif
#ifdef TX_ENABLE_EVENT_TRACE
/* Pickup the return IP address. */
message_ptr = (ULONG *)packet_ptr -> nx_packet_prepend_ptr;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ICMP_RECEIVE, ip_ptr, *(message_ptr - 2), packet_ptr, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Unhandled ICMP message, just release it. */
_nx_packet_release(packet_ptr);
}
return;
}

View File

@ -0,0 +1,193 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_icmp.h"
#include "nx_packet.h"
#include "tx_thread.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_packet_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function receives an ICMP packet from the IP receive */
/* processing. If this routine is called from an ISR, it simply */
/* places the new message on the ICMP message queue, and wakes up the */
/* IP processing thread. If this routine is called from the IP helper */
/* thread, then the ICMP message is processed directly. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_icmp_packet_process Process ICMP packet */
/* tx_event_flags_set Set event flags for IP helper */
/* thread */
/* */
/* CALLED BY */
/* */
/* _nx_ip_packet_receive Dispatch received IP packets */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_icmp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
#ifdef NX_ENABLE_ICMP_ADDRESS_CHECK
NX_IP_HEADER *ip_header_ptr;
NX_INTERFACE *interface_ptr;
#endif /* NX_ENABLE_ICMP_ADDRESS_CHECK */
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP total messages received counter. */
ip_ptr -> nx_ip_icmp_total_messages_received++;
#endif
#ifndef NX_DISABLE_RX_SIZE_CHECKING
/* Check for valid packet length. */
if (packet_ptr -> nx_packet_length < sizeof(NX_ICMP_HEADER))
{
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP invalid packet error. */
ip_ptr -> nx_ip_icmp_invalid_packets++;
#endif
/* Invalid packet length, just release it. */
_nx_packet_release(packet_ptr);
/* The function is complete, just return! */
return;
}
#endif
#ifdef NX_ENABLE_ICMP_ADDRESS_CHECK
/* An ICMP Echo Request destined to an IP broadcast or IP multicast address
MAY be silently discarded.
RFC 1122, Section 3.2.2.6, Page42. */
/* Pickup the IP header and interface. */
ip_header_ptr = (NX_IP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IP_HEADER));
interface_ptr = packet_ptr -> nx_packet_ip_interface;
if (
/* Check for Multicast address */
((ip_header_ptr -> nx_ip_header_destination_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE) ||
/* Check for subnet-directed broadcast */
(((ip_header_ptr -> nx_ip_header_destination_ip & interface_ptr -> nx_interface_ip_network_mask) == interface_ptr -> nx_interface_ip_network) &&
((ip_header_ptr -> nx_ip_header_destination_ip & ~(interface_ptr -> nx_interface_ip_network_mask)) == ~(interface_ptr -> nx_interface_ip_network_mask))) ||
/* Check for local subnet address */
(ip_header_ptr -> nx_ip_header_destination_ip == interface_ptr -> nx_interface_ip_network) ||
/* Check for limited broadcast */
(ip_header_ptr -> nx_ip_header_destination_ip == NX_IP_LIMITED_BROADCAST)
)
{
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP invalid packet error. */
ip_ptr -> nx_ip_icmp_invalid_packets++;
#endif
/* Invalid packet length, just release it. */
_nx_packet_release(packet_ptr);
/* The function is complete, just return! */
return;
}
#endif /* NX_ENABLE_ICMP_ADDRESS_CHECK */
/* Determine if this routine is being called from an ISR. */
if (TX_THREAD_GET_SYSTEM_STATE())
{
/* If non-zero, we are in an ISR. Just place the message on the
ICMP message queue and wakeup the IP helper thread. */
/* Disable interrupts. */
TX_DISABLE
/* Add the packet to the ICMP message queue. */
if (ip_ptr -> nx_ip_icmp_queue_head)
{
/* Link the current packet to the list head. */
packet_ptr -> nx_packet_queue_next = ip_ptr -> nx_ip_icmp_queue_head;
}
else
{
/* Empty queue, add to the head of the ICMP message queue. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
}
/* Update the queue head pointer. */
ip_ptr -> nx_ip_icmp_queue_head = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
/* Wakeup IP thread for processing one or more messages in the ICMP queue. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_ICMP_EVENT, TX_OR);
}
else
{
/* The IP message was deferred, so this routine is called from the IP helper
thread and thus may call the ICMP processing directly. */
_nx_icmp_packet_process(ip_ptr, packet_ptr);
}
}

307
common/src/nx_icmp_ping.c Normal file
View File

@ -0,0 +1,307 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_icmp.h"
#include "nx_packet.h"
#include "nx_ip.h"
#include "tx_thread.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_ping PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds an ICMP ping request packet and calls the */
/* associated driver to send it out on the network. The function will */
/* then suspend for the specified time waiting for the ICMP ping */
/* response. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* ip_address IP address to ping */
/* data_ptr User Data pointer */
/* data_size Size of User Data */
/* response_ptr Pointer to Response Packet */
/* wait_option Suspension option */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_icmp_checksum_compute Computer ICMP checksum */
/* _nx_ip_packet_send IP packet send function */
/* _nx_ip_route_find Find a suitable outgoing */
/* interface. */
/* _nx_packet_allocate Allocate a packet for the */
/* ICMP ping request */
/* _nx_packet_release Release packet on error */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* _tx_thread_system_suspend Suspend thread */
/* _tx_thread_system_preempt_check Check for preemption */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_icmp_ping(NX_IP *ip_ptr, ULONG ip_address,
CHAR *data_ptr, ULONG data_size,
NX_PACKET **response_ptr, ULONG wait_option)
{
TX_INTERRUPT_SAVE_AREA
UINT status;
NX_PACKET *request_ptr;
NX_ICMP_HEADER *header_ptr;
ULONG sequence;
TX_THREAD *thread_ptr;
#ifndef NX_DISABLE_ICMP_TX_CHECKSUM
ULONG checksum;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_ICMP_PING, ip_ptr, ip_address, data_ptr, data_size, NX_TRACE_ICMP_EVENTS, 0, 0)
/* Clear the destination pointer. */
* response_ptr = NX_NULL;
/* Allocate a packet to place the ICMP echo request message in. */
status = _nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &request_ptr, NX_ICMP_PACKET, wait_option);
if (status)
{
/* Error getting packet, so just get out! */
return(status);
}
/* Determine if the size of the data and the ICMP header is larger than
the packet payload area. */
if ((data_size + NX_ICMP_HEADER_SIZE) > (ULONG)(request_ptr -> nx_packet_data_end - request_ptr -> nx_packet_append_ptr))
{
/* Release the packet. */
_nx_packet_release(request_ptr);
/* Error, the data area is too big for the default packet payload. */
return(NX_OVERFLOW);
}
/* Find a suitable interface for sending the ping packet. */
if (_nx_ip_route_find(ip_ptr, ip_address, &request_ptr -> nx_packet_ip_interface, &request_ptr -> nx_packet_next_hop_address) != NX_SUCCESS)
{
/* Release the packet. */
_nx_packet_release(request_ptr);
return(NX_IP_ADDRESS_ERROR);
}
#ifndef NX_DISABLE_ICMP_INFO
/* Increment the ICMP ping count. */
ip_ptr -> nx_ip_pings_sent++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_ICMP_SEND, ip_ptr, ip_address, request_ptr, (((ULONG)NX_ICMP_ECHO_REQUEST_TYPE) << 24), NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Calculate the ICMP echo request message size and store it in the
packet header. */
request_ptr -> nx_packet_length = data_size + NX_ICMP_HEADER_SIZE;
/* Setup the append pointer to the end of the message. */
request_ptr -> nx_packet_append_ptr = request_ptr -> nx_packet_prepend_ptr + (data_size + NX_ICMP_HEADER_SIZE);
/* Build the ICMP request packet. */
/* Setup the pointer to the message area. */
header_ptr = (NX_ICMP_HEADER *)request_ptr -> nx_packet_prepend_ptr;
/* Write the ICMP type into the message. Use the lower 16-bits of the IP address for
the ICMP identifier. */
header_ptr -> nx_icmp_header_word_0 = (ULONG)(NX_ICMP_ECHO_REQUEST_TYPE << 24);
sequence = (ip_ptr -> nx_ip_icmp_sequence++ & NX_LOWER_16_MASK);
header_ptr -> nx_icmp_header_word_1 = (ULONG)(request_ptr -> nx_packet_ip_interface -> nx_interface_ip_address << 16) | sequence;
/* Copy the data into the packet payload area. */
memcpy(request_ptr -> nx_packet_prepend_ptr + sizeof(NX_ICMP_HEADER), data_ptr, data_size);
/* If NX_LITTLE_ENDIAN is defined, the headers need to be swapped to match
that of the data area. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0);
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_1);
#ifndef NX_DISABLE_ICMP_TX_CHECKSUM
/* Compute the checksum of the ICMP packet. */
checksum = _nx_icmp_checksum_compute(request_ptr);
/* If NX_LITTLE_ENDIAN is defined, the headers need to be swapped back so
we can place the checksum in the ICMP header. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0);
/* Place the checksum into the first header word. */
header_ptr -> nx_icmp_header_word_0 = header_ptr -> nx_icmp_header_word_0 | (~checksum & NX_LOWER_16_MASK);
/* If NX_LITTLE_ENDIAN is defined, the first header word needs to be swapped
back. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0);
#endif
/* Obtain the IP internal mutex to prevent against possible suspension later in the
call to IP packet send. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Disable interrupts. */
TX_DISABLE
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Pickup thread pointer. */
thread_ptr = _tx_thread_current_ptr;
/* Determine if the request specifies suspension. */
if (wait_option)
{
/* Prepare for suspension of this thread. */
/* Setup cleanup routine pointer. */
thread_ptr -> tx_thread_suspend_cleanup = _nx_icmp_cleanup;
thread_ptr -> tx_thread_suspend_status = NX_NO_RESPONSE;
/* Setup cleanup information, i.e. this pool control
block. */
thread_ptr -> tx_thread_suspend_control_block = (void *)ip_ptr;
/* Save the return packet pointer address as well. */
thread_ptr -> tx_thread_additional_suspend_info = (void *)response_ptr;
/* Save the sequence number so this can be matched up with an ICMP
response later. */
thread_ptr -> tx_thread_suspend_info = sequence;
/* Setup suspension list. */
if (ip_ptr -> nx_ip_icmp_ping_suspension_list)
{
/* This list is not NULL, add current thread to the end. */
thread_ptr -> tx_thread_suspended_next =
ip_ptr -> nx_ip_icmp_ping_suspension_list;
thread_ptr -> tx_thread_suspended_previous =
(ip_ptr -> nx_ip_icmp_ping_suspension_list) -> tx_thread_suspended_previous;
((ip_ptr -> nx_ip_icmp_ping_suspension_list) -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
thread_ptr;
(ip_ptr -> nx_ip_icmp_ping_suspension_list) -> tx_thread_suspended_previous = thread_ptr;
}
else
{
/* No other threads are suspended. Setup the head pointer and
just setup this threads pointers to itself. */
ip_ptr -> nx_ip_icmp_ping_suspension_list = thread_ptr;
thread_ptr -> tx_thread_suspended_next = thread_ptr;
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
}
/* Increment the suspended thread count. */
ip_ptr -> nx_ip_icmp_ping_suspended_count++;
/* Set the state to suspended. */
thread_ptr -> tx_thread_state = TX_TCP_IP;
/* Set the suspending flag. */
thread_ptr -> tx_thread_suspending = TX_TRUE;
/* Save the timeout value. */
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
}
/* Restore interrupts. */
TX_RESTORE
/* Send the ICMP packet to the IP component. */
_nx_ip_packet_send(ip_ptr, request_ptr, ip_address,
NX_IP_NORMAL, NX_IP_TIME_TO_LIVE, NX_IP_ICMP, NX_FRAGMENT_OKAY);
/* If wait option is requested, suspend the thread. */
if (wait_option)
{
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Call actual thread suspension routine. */
_tx_thread_system_suspend(thread_ptr);
/* Return the status from the thread control block. */
return(thread_ptr -> tx_thread_suspend_status);
}
else
{
/* Disable interrupts. */
TX_DISABLE
/* Release preemption disable. */
_tx_thread_preempt_disable--;
/* Restore interrupts. */
TX_RESTORE
/* Release the protection mutex. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Check for preemption. */
_tx_thread_system_preempt_check();
/* Immediate return, return error completion. */
return(NX_NO_RESPONSE);
}
}

View File

@ -0,0 +1,106 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Control Message Protocol (ICMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_packet.h"
#include "nx_ip.h"
#include "nx_icmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_icmp_queue_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the ICMP receive packet queue. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_icmp_packet_process Process ICMP packet */
/* */
/* CALLED BY */
/* */
/* _nx_ip_thread_entry IP helper thread processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_icmp_queue_process(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_PACKET *queue_head;
NX_PACKET *packet_ptr;
/* Disable interrupts. */
TX_DISABLE
/* Remove the ICMP message queue from the IP structure. */
queue_head = ip_ptr -> nx_ip_icmp_queue_head;
ip_ptr -> nx_ip_icmp_queue_head = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Walk through the entire ICMP message queue and process packets
one by one. */
while (queue_head)
{
/* Pickup the first queued ICMP message and remove it from the
ICMP queue. */
packet_ptr = queue_head;
queue_head = queue_head -> nx_packet_queue_next;
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Process the packet. */
_nx_icmp_packet_process(ip_ptr, packet_ptr);
}
}

102
common/src/nx_igmp_enable.c Normal file
View File

@ -0,0 +1,102 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enables the IGMP management component for the */
/* specified IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_event_flags_set Set deferred IGMP enable */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_enable(NX_IP *ip_ptr)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IGMP_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_IGMP_EVENTS, 0, 0)
#ifndef NX_DISABLE_IGMPV2
/* Set the IGMP protocol to the default version supported by NetX, IGMPv2. */
ip_ptr -> nx_ip_igmp_router_version = NX_IGMP_HOST_VERSION_2;
#endif
/* Setup the IGMP packet receive routine, which enables the IGMP component. */
ip_ptr -> nx_ip_igmp_packet_receive = _nx_igmp_packet_receive;
/* Setup the IGMP periodic processing routine, which enables the IGMP component. */
ip_ptr -> nx_ip_igmp_periodic_processing = _nx_igmp_periodic_processing;
/* Setup the IGMP queue processing routine, which processes deferred IGMP
requests. */
ip_ptr -> nx_ip_igmp_queue_process = _nx_igmp_queue_process;
/* Wakeup IP helper thread to process the IGMP deferred enable. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_IGMP_ENABLE_EVENT, TX_OR);
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,128 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves various IGMP information associated with */
/* the specified IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* igmp_reports_sent Destination for the number */
/* of IGMP reports sent */
/* igmp_queries_received Destination for the number */
/* of IGMP queries received */
/* igmp_checksum_errors Destination for the number */
/* of IGMP checksum errors */
/* current_groups_joined Destination for the number */
/* of IGMP multicast groups */
/* currently joined */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_info_get(NX_IP *ip_ptr, ULONG *igmp_reports_sent, ULONG *igmp_queries_received,
ULONG *igmp_checksum_errors, ULONG *current_groups_joined)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IGMP_INFO_GET, ip_ptr, ip_ptr -> nx_ip_igmp_reports_sent, ip_ptr -> nx_ip_igmp_queries_received, ip_ptr -> nx_ip_igmp_groups_joined, NX_TRACE_IGMP_EVENTS, 0, 0)
/* Obtain protection on this IP instance. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Determine if IGMP reports sent is wanted. */
if (igmp_reports_sent)
{
/* Return the number of IGMP reports sent by this IP instance. */
*igmp_reports_sent = ip_ptr -> nx_ip_igmp_reports_sent;
}
/* Determine if IGMP queries received is wanted. */
if (igmp_queries_received)
{
/* Return the number of IGMP queries received by this IP instance. */
*igmp_queries_received = ip_ptr -> nx_ip_igmp_queries_received;
}
/* Determine if IGMP checksum errors is wanted. */
if (igmp_checksum_errors)
{
/* Return the number of IGMP checksum errors by this IP instance. */
*igmp_checksum_errors = ip_ptr -> nx_ip_igmp_checksum_errors;
}
/* Determine if the number of IGMP multicast groups joined is wanted. */
if (current_groups_joined)
{
/* Return the number of IGMP multicast groups joined is wanted. */
*current_groups_joined = ip_ptr -> nx_ip_igmp_groups_joined;
}
/* Release the protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,226 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_interface_report_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds and sends an IGMP report. If it is a JOIN */
/* report, the IP nx_igmp_reports_sent statistic is incremented. */
/* */
/* Note: An IGMPv1 host does not send a LEAVE message. The caller in */
/* that case, _nx_igmp_multicast_interface_leave_internal, checks the */
/* IGMP host version and only calls this function for IGMPv2 hosts. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* group_address Multicast group to join */
/* interface_index Index to the interface */
/* is_joining Indicate if joining or leaving*/
/* NX_TRUE = send join report */
/* NX_FALSE = send leave report*/
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* NX_ENTRY_NOT_FOUND Entry not in multicast table */
/* */
/* CALLS */
/* */
/* _nx_ip_packet_send Send packet from the IP layer */
/* _nx_packet_allocate Allocate a packet for report */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* nx_igmp_periodic_processing Performs periodic IGMP tasks */
/* nx_igmp_multicast_leave Processes a LEAVE report for */
/* transmission to all routers */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_interface_report_send(NX_IP *ip_ptr, ULONG group_address, UINT interface_index, UINT is_joining)
{
UINT status;
ULONG checksum;
ULONG temp;
NX_PACKET *packet_ptr;
NX_IGMP_HEADER *header_ptr;
/* Obtain the IP mutex so we can search the multicast join list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Build an IGMP host response packet and send it! */
/* Allocate an packet to place the IGMP host response message in. */
status = _nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &packet_ptr, (ULONG)(NX_IGMP_PACKET + NX_IGMP_HEADER_SIZE), TX_NO_WAIT);
/* Check for error. */
if (status)
{
/* Packet allocation failed. Release the mutex and return error status. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
return(status);
}
/* Prepare an IGMP response and send on the "all hosts" multicast
address. */
#ifndef NX_DISABLE_IGMP_INFO
/* Increment the IGMP reports sent count. */
if (is_joining == NX_TRUE)
{
ip_ptr -> nx_ip_igmp_reports_sent++;
}
#endif
/* Calculate the IGMP response message size and store it in the
packet header. */
/*lint -e{644} suppress variable might not be initialized, since "packet_ptr" was initialized as long as status is NX_SUCCESS. */
packet_ptr -> nx_packet_length = NX_IGMP_HEADER_SIZE;
/* Setup the prepend pointer. */
packet_ptr -> nx_packet_prepend_ptr -= NX_IGMP_HEADER_SIZE;
packet_ptr -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
/* Build the IGMP host response packet. */
/* Setup the pointer to the message area. */
/*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
header_ptr = (NX_IGMP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
#ifndef NX_DISABLE_IGMPV2
/* Build the IGMPv2 response message. */
/* Is the router using IGMPv1? */
if (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_1)
{
#endif /* NX_DISABLE_IGMPV2 */
/* Yes; Set the header fields with the max response time
zero and the version/type 0x12. */
header_ptr -> nx_igmp_header_word_0 = (ULONG)(NX_IGMP_VERSION | NX_IGMP_HOST_RESPONSE_TYPE);
header_ptr -> nx_igmp_header_word_1 = group_address;
#ifndef NX_DISABLE_IGMPV2
}
/* The router is running the IGMPv2 (or higher) protocol. */
else
{
/* Indicate if the report is a join or leave report. */
if (is_joining)
{
header_ptr -> nx_igmp_header_word_0 = (ULONG)(NX_IGMP_HOST_V2_JOIN_TYPE);
}
else
{
header_ptr -> nx_igmp_header_word_0 = (ULONG)(NX_IGMP_HOST_V2_LEAVE_TYPE);
}
header_ptr -> nx_igmp_header_word_1 = group_address;
}
#endif /* NX_DISABLE_IGMPV2 */
/* 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 = header_ptr -> nx_igmp_header_word_0 | (~checksum & NX_LOWER_16_MASK);
/* 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);
/* Note that because this is a class D/multicast address we can set next hop
for sending this IGMP message directly. */
/* Send the IGMP response packet out! */
if (is_joining == NX_TRUE)
{
packet_ptr -> nx_packet_next_hop_address = group_address;
/* For JOIN reports, set the packet destination to the group address. */
_nx_ip_packet_send(ip_ptr, packet_ptr,
group_address,
NX_IP_NORMAL, NX_IGMP_TTL, NX_IP_IGMP, NX_FRAGMENT_OKAY);
}
else
{
packet_ptr -> nx_packet_next_hop_address = NX_ALL_ROUTERS_ADDRESS;
/* For LEAVE reports, set the destination to ALL ROUTERS as per RFC 2236 Section 3 page 4.*/
_nx_ip_packet_send(ip_ptr, packet_ptr,
NX_ALL_ROUTERS_ADDRESS,
NX_IP_NORMAL, NX_IGMP_TTL, NX_IP_IGMP, NX_FRAGMENT_OKAY);
}
/* Release the protection over the IP instance. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
return NX_SUCCESS;
}

View File

@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_loopback_disable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function disables loopback for all subsequent IGMP groups */
/* joined by the host. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_loopback_disable(NX_IP *ip_ptr)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IGMP_LOOPBACK_DISABLE, ip_ptr, 0, 0, 0, NX_TRACE_IGMP_EVENTS, 0, 0)
/* Clear the global IGMP loopback flag. All subsequent IGMP group join
requests will have loopback disabled. */
ip_ptr -> nx_ip_igmp_global_loopback_enable = NX_FALSE;
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_loopback_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enables loopback for all subsequent IGMP groups */
/* joined by the host. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_loopback_enable(NX_IP *ip_ptr)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IGMP_LOOPBACK_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_IGMP_EVENTS, 0, 0)
/* Set the global IGMP loopback flag. All subsequent IGMP group join
requests will have loopback enabled. */
ip_ptr -> nx_ip_igmp_global_loopback_enable = NX_TRUE;
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,104 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_multicast_check PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks the list of joined multicast addresses to see */
/* if the incoming address matches. If the specified group is */
/* "all hosts" or if a match is found, NX_TRUE is returned to the */
/* caller. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* group Multicast group IP address */
/* */
/* OUTPUT */
/* */
/* NX_TRUE If a match is found */
/* NX_FALSE Otherwise */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _nx_ip_packet_receive Raw IP packet receive */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_multicast_check(NX_IP *ip_ptr, ULONG group, NX_INTERFACE *nx_interface)
{
UINT i;
ULONG *join_list_ptr;
/* Check for "all hosts" group. We always assume all hosts membership. */
if (group == NX_ALL_HOSTS_ADDRESS)
{
return(NX_TRUE);
}
/* Loop through the IP multicast join list to find the matching group that is being
responded to by another host on this same network. */
join_list_ptr = &(ip_ptr -> nx_ip_igmp_join_list[0]);
for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
{
/* Check for a match. */
if ((*join_list_ptr++ == group) && (nx_interface == ip_ptr -> nx_ip_igmp_join_interface_list[i]))
{
return(NX_TRUE);
}
}
/* Otherwise, we have searched the entire list, return false. */
return(NX_FALSE);
}

View File

@ -0,0 +1,181 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_multicast_interface_join PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles the request to join the specified multicast */
/* group on a specified network interface. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* group_address Multicast group to join */
/* nx_interface_index Index to the NetX interface */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* (ip_link_driver) Associated IP link driver */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_multicast_interface_join(NX_IP *ip_ptr, ULONG group_address, UINT nx_interface_index)
{
UINT i;
UINT first_free;
ULONG *join_list_ptr;
NX_IP_DRIVER driver_request;
NX_INTERFACE *nx_interface;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IGMP_MULTICAST_JOIN, ip_ptr, group_address, nx_interface_index, 0, NX_TRACE_IGMP_EVENTS, 0, 0)
/* Obtain the IP mutex so we can search the multicast join list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
nx_interface = &ip_ptr -> nx_ip_interface[nx_interface_index];
/* Search the multicast join list for either the same group request. */
first_free = NX_MAX_MULTICAST_GROUPS;
join_list_ptr = &(ip_ptr -> nx_ip_igmp_join_list[0]);
for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
{
/* Determine if the specified entry is already in the multicast join list. */
if (*join_list_ptr == group_address)
{
/* Yes, we have found the same entry. The only thing required in this
case is to increment the join count and return. */
ip_ptr -> nx_ip_igmp_join_count[i]++;
/* Release the IP protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return success! */
return(NX_SUCCESS);
}
/* Check for an empty entry. */
if ((*join_list_ptr == 0) && (first_free == NX_MAX_MULTICAST_GROUPS))
{
/* Remember the first free entry. */
first_free = i;
}
/* Move to the next entry in the join list. */
join_list_ptr++;
}
/* At this point, we have a new entry. First, check to see if there is an available
entry. */
if (first_free == NX_MAX_MULTICAST_GROUPS)
{
/* Release the protection of the IP instance. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return an error code to indicate there are no more group addresses
available. */
return(NX_NO_MORE_ENTRIES);
}
/* 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_ptr;
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 | (group_address & NX_IP_MULTICAST_MASK);
driver_request.nx_ip_driver_interface = nx_interface;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_MULTICAST_JOIN, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
(nx_interface -> nx_interface_link_driver_entry) (&driver_request);
/* Check the return driver status. */
if (driver_request.nx_ip_driver_status != NX_SUCCESS)
{
/* Release the protection of the IP instance. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return an error code to indicate there are no more group addresses
available. */
return(NX_NO_MORE_ENTRIES);
}
/* Set it up in the IP control structures. */
ip_ptr -> nx_ip_igmp_join_list[first_free] = group_address;
ip_ptr -> nx_ip_igmp_join_interface_list[first_free] = nx_interface;
ip_ptr -> nx_ip_igmp_join_count[first_free] = 1;
ip_ptr -> nx_ip_igmp_update_time[first_free] = 1; /* Update on next IGMP periodic */
ip_ptr -> nx_ip_igmp_group_loopback_enable[first_free] = ip_ptr -> nx_ip_igmp_global_loopback_enable;
#ifndef NX_DISABLE_IGMP_INFO
/* Increment the IGMP groups joined count. */
ip_ptr -> nx_ip_igmp_groups_joined++;
#endif
/* Release the protection over the IP instance. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,77 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_multicast_join PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles the request to join the specified multicast */
/* group. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* group_address Multicast group to join */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_igmp_multicast_interface_join Join Multicast group */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_multicast_join(NX_IP *ip_ptr, ULONG group_address)
{
/* Default to interface 0. */
return(_nx_igmp_multicast_interface_join(ip_ptr, group_address, 0));
}

View File

@ -0,0 +1,188 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_multicast_leave PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles the request to leave the specified multicast */
/* group. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* group_address Multicast group to leave */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* (ip_link_driver) Associated IP link driver */
/* nx_igmp_interface_report_send Send IGMP group report */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_igmp_multicast_leave(NX_IP *ip_ptr, ULONG group_address)
{
UINT i;
#ifndef NX_DISABLE_IGMPV2
UINT interface_index = 0;
#endif
ULONG *join_list_ptr;
NX_IP_DRIVER driver_request;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IGMP_MULTICAST_LEAVE, ip_ptr, group_address, 0, 0, NX_TRACE_IGMP_EVENTS, 0, 0)
/* Obtain the IP mutex so we can search the multicast join list. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Search the multicast join list for either the same group request. */
join_list_ptr = &(ip_ptr -> nx_ip_igmp_join_list[0]);
for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
{
/* Determine if the specified entry is present. */
if (*join_list_ptr == group_address)
{
/* Yes, we have found the same entry. */
#ifndef NX_DISABLE_IGMPV2
UINT index;
NX_INTERFACE *nx_interface = ip_ptr -> nx_ip_igmp_join_interface_list[i];
#endif
/* Decrease the join count. */
ip_ptr -> nx_ip_igmp_join_count[i]--;
/* Determine if there are no other join requests. */
if (ip_ptr -> nx_ip_igmp_join_count[i] == 0)
{
/* Clear the group join value. */
*join_list_ptr = 0;
/* Un-register the new multicast group with the underlying driver. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_MULTICAST_LEAVE;
driver_request.nx_ip_driver_physical_address_msw = NX_IP_MULTICAST_UPPER;
driver_request.nx_ip_driver_physical_address_lsw = NX_IP_MULTICAST_LOWER | (group_address & NX_IP_MULTICAST_MASK);
driver_request.nx_ip_driver_interface = ip_ptr -> nx_ip_igmp_join_interface_list[i];
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_MULTICAST_LEAVE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
(ip_ptr -> nx_ip_igmp_join_interface_list[i] -> nx_interface_link_driver_entry) (&driver_request);
#ifdef NX_DISABLE_IGMPV2
/* Clear the interface entry for version IGMPv1. We don't need it anymore. */
ip_ptr -> nx_ip_igmp_join_interface_list[i] = NX_NULL;
#endif
#ifndef NX_DISABLE_IGMP_INFO
/* Decrement the IGMP groups joined count. */
ip_ptr -> nx_ip_igmp_groups_joined--;
#endif
#ifndef NX_DISABLE_IGMPV2
/* IGMPv2 hosts should send a leave group message. IGMPv1
hosts do not. */
if (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_1)
{
/* Release the IP protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return success! */
return(NX_SUCCESS);
}
/* Find the interface for this group address. */
for (index = 0; index < NX_MAX_PHYSICAL_INTERFACES; index++)
{
if (nx_interface == &(ip_ptr -> nx_ip_interface[index]))
{
/* Found it. */
interface_index = index;
break;
}
}
/* Build and send the leave report packet. */
_nx_igmp_interface_report_send(ip_ptr, group_address, interface_index, NX_FALSE);
#endif /* NX_DISABLE_IGMPV2 */
}
/* Release the IP protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return success! */
return(NX_SUCCESS);
}
/* Move to the next entry in the join list. */
join_list_ptr++;
}
/* The group address was not found in the multicast join list.
Release the protection of the IP instance and quit. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return an error code. */
return(NX_ENTRY_NOT_FOUND);
}

View File

@ -0,0 +1,360 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_packet.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_packet_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles reception of IGMP packets on the "all hosts" */
/* multicast address. There are basically two types of IGMP packets */
/* that will arrive. Routers send IGMP query messages while hosts send*/
/* IGMP responses (join requests). If an IGMP join request for a group */
/* address this host belongs to is received, that will cancel sending */
/* a join request by this host. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* packet_ptr IGMP packet pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_packet_release Release IGMP packet */
/* tx_time_get Get current time */
/* */
/* CALLED BY */
/* */
/* _nx_igmp_packet_receive IGMP packet receive */
/* _nx_igmp_queue_process IGMP queue processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_igmp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
UINT i;
ULONG update_time;
NX_IGMP_HEADER *header_ptr;
USHORT max_update_time;
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;
/* First verify the checksum is correct. */
checksum = 0;
/* Setup the length of the packet checksum. */
length = packet_ptr -> nx_packet_length;
/* Determine if we need to add a padding byte. */
if (((length / sizeof(USHORT)) * sizeof(USHORT)) != length)
{
/* We have single byte alignment and we need two byte alignment. */
length++;
/* Determine if there is a last packet pointer. */
if (packet_ptr -> nx_packet_last)
{
/* Multi-packet message, add a zero byte at the end. */
*((packet_ptr -> nx_packet_last) -> nx_packet_append_ptr) = 0;
}
else
{
/* Write a zero byte at the end of the first and only packet. */
*(packet_ptr -> nx_packet_append_ptr) = 0;
}
}
/* 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;
/* 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;
}
}
checksum = ~checksum & NX_LOWER_16_MASK;
/* Determine if the checksum is valid. */
if (checksum)
{
/* It is not. By RFC requirements we should not accept this packet. */
/* Increment the IGMP invalid packet error. */
ip_ptr -> nx_ip_igmp_invalid_packets++;
/* Increment the IGMP checksum error count. */
ip_ptr -> nx_ip_igmp_checksum_errors++;
/* Toss this IGMP packet out. */
_nx_packet_release(packet_ptr);
return;
}
/* Swap the IGMP headers back to host byte order for the checksum
calculation. */
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0);
NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_1);
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IGMP_RECEIVE, ip_ptr, *(((ULONG *)packet_ptr -> nx_packet_prepend_ptr) - 2), packet_ptr, header_ptr -> nx_igmp_header_word_0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Determine the type of IGMP message received. Note that an IGMPv1 host will respond
to an IGMPv2 general query but not process the maximum response time field. */
if ((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_ROUTER_QUERY_TYPE)
{
#ifndef NX_DISABLE_IGMP_INFO
/* Increment the IGMP queries received count. */
ip_ptr -> nx_ip_igmp_queries_received++;
#endif
/* Set the max response time recommended by RFC 1112 set by host in seconds. In a
IGMPv2 network, the router may set a different max time in its IGMP membership queries. */
max_update_time = NX_IGMP_MAX_UPDATE_TIME;
#ifndef NX_DISABLE_IGMPV2
/* Determine the IGMP version the sender (router) is using. */
/* Is the max response time non zero? */
if ((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_MAX_RESP_TIME_MASK) != NX_NULL)
{
/* Yes, this must be an IGMPv2 router. */
ip_ptr -> nx_ip_igmp_router_version = NX_IGMP_HOST_VERSION_2;
}
else
{
/* No; IGMPv1 requires setting this field to zero. */
ip_ptr -> nx_ip_igmp_router_version = NX_IGMP_HOST_VERSION_1;
}
/* Is this packet from an IGMPv2 router? */
if (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_2)
{
/* Yes; parse the max response time from the IGMP header. */
max_update_time = (USHORT)(((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_MAX_RESP_TIME_MASK) >> 16) & 0x000000FF);
/* Convert from tenths of a second to seconds. */
max_update_time /= 10;
}
#endif
/* Then generate a random update time initially in timer ticks for the delay. */
update_time = tx_time_get() & 0xF;
/* Check we have a valid non zero update time that does not exceed the
maximum response time. */
if ((update_time > max_update_time) || (update_time == NX_NULL))
{
/* If not, wrap the update time back to one second. */
update_time = 1;
}
/* Loop through the multicast join list and assign an arbitrary timeout to
respond between 1 and maximum response time for each group. */
for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
{
/* Is there a group address in this slot? */
if (ip_ptr -> nx_ip_igmp_join_list[i] == NX_NULL)
{
/* No, skip doing further processing. */
continue;
}
/* Does the group address in the header match our join list? */
if ((ip_ptr -> nx_ip_igmp_join_list[i] != header_ptr -> nx_igmp_header_word_1) &&
/* or is this a general membership query? */
(header_ptr -> nx_igmp_header_word_1 != NX_NULL))
{
/* No; so no need to update the timer, skip to the next group in the host list. */
continue;
}
/* Is the current host group running timer less than the max delay? */
if ((ip_ptr -> nx_ip_igmp_update_time[i] < max_update_time) &&
(ip_ptr -> nx_ip_igmp_update_time[i] != NX_NULL))
{
/* Yes; Let the current timer timeout. Skip to the next group. */
continue;
}
/* Set the timeout for this multicast group. */
ip_ptr -> nx_ip_igmp_update_time[i] = update_time;
/* Then increment the update time for the next host group so the update/expiration times
are separated by one second. This avoids bursts of IGMP reports to the server. */
update_time++;
/* Check after each multicast group that we have not exceeded the maximum response time. */
if (update_time > max_update_time)
{
/* We have, so wrap the update time back to one. */
update_time = 1;
}
}
}
#ifndef NX_DISABLE_IGMPV2
/* Is this another IGMPv1 host's join request? */
else if (((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE) ||
/* ...Or another 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? */
else if ((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE)
#endif
{
/* Yes; Loop through the host multicast join list to find a match. */
for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
{
/* Compare the group address in the header with the host list. Is this a match? */
if (ip_ptr -> nx_ip_igmp_join_list[i] == header_ptr -> nx_igmp_header_word_1)
{
/* Yes; Clear the update time. This will cancel sending a join
request for the same multicast group. */
ip_ptr -> nx_ip_igmp_update_time[i] = 0;
break;
}
}
}
/* Release the IGMP packet. */
_nx_packet_release(packet_ptr);
}

View File

@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_packet.h"
#include "nx_igmp.h"
#include "nx_ip.h"
#include "tx_thread.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_packet_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles reception of IGMP packets on the "all hosts" */
/* multicast address. If this routine is called from an ISR, the */
/* IGMP packet is queued. Otherwise, if this routine is called from */
/* the IP helper thread, the processing of the IGMP packet is called */
/* directly. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* packet_ptr IGMP packet pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_igmp_packet_process Process the IGMP packet */
/* tx_event_flags_set Set event flags for IP helper */
/* thread */
/* */
/* CALLED BY */
/* */
/* _nx_ip_packet_receive Raw IP packet receive */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_igmp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
#ifndef NX_DISABLE_RX_SIZE_CHECKING
/* Check for valid packet length. */
if (packet_ptr -> nx_packet_length < sizeof(NX_IGMP_HEADER))
{
#ifndef NX_DISABLE_IGMP_INFO
/* Increment the IGMP invalid packet error. */
ip_ptr -> nx_ip_igmp_invalid_packets++;
#endif
/* Invalid packet length, just release it. */
_nx_packet_release(packet_ptr);
/* The function is complete, just return! */
return;
}
#endif
/* Determine if this routine is being called from an ISR. */
if (TX_THREAD_GET_SYSTEM_STATE())
{
/* If non-zero, we are in an ISR. Just place the message on the
IGMP message queue and wakeup the IP helper thread. */
/* Disable interrupts. */
TX_DISABLE
/* Add the packet to the IGMP message queue. */
if (ip_ptr -> nx_ip_igmp_queue_head)
{
/* Link the current packet to the list head. */
packet_ptr -> nx_packet_queue_next = ip_ptr -> nx_ip_igmp_queue_head;
}
else
{
/* Empty queue, add to the head of the IGMP message queue. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
}
/* Update the queue head pointer. */
ip_ptr -> nx_ip_igmp_queue_head = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
/* Wakeup IP thread for processing one or more messages in the IGMP queue. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_IGMP_EVENT, TX_OR);
}
else
{
/* The IP message was deferred, so this routine is called from the IP helper
thread and thus may call the IGMP processing directly. */
_nx_igmp_packet_process(ip_ptr, packet_ptr);
}
}

View File

@ -0,0 +1,155 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_periodic_processing PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles the sending of periodic processing of IGMP */
/* messages. */
/* */
/* INPUT */
/* */
/* ip_ptr IP instance pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* nx_igmp_interface_report_send Send IGMP group report */
/* */
/* CALLED BY */
/* */
/* _nx_ip_thread_entry IP helper thread */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_igmp_periodic_processing(NX_IP *ip_ptr)
{
UINT i;
UINT status;
UINT interface_index = 0;
ULONG *join_list_ptr;
UINT sent_count = 0;
/* Search the multicast join list for pending IGMP responses. */
join_list_ptr = &(ip_ptr -> nx_ip_igmp_join_list[0]);
for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
{
/* Determine if the specified entry is active. */
if (*join_list_ptr)
{
/* Now determine if a response is pending. */
if (ip_ptr -> nx_ip_igmp_update_time[i] > 0)
{
/* Yes, it is active. Decrement and check for expiration. */
/* We don't want to decrement a join group if we cannot send it. Check
if we've already sent a packet on this periodic. */
if (sent_count > 0)
{
/* We have. So only decrement groups with a update time > 1. */
if (ip_ptr -> nx_ip_igmp_update_time[i] > 1)
{
/* Ok to decrement. */
ip_ptr -> nx_ip_igmp_update_time[i]--;
}
/* Else don't decrement because we cannot send on this periodic; we've already sent out a packet. */
}
else
{
/* No packets sent out yet. Ok to decrement this group. */
ip_ptr -> nx_ip_igmp_update_time[i]--;
}
/* Has time expired and have we not sent an IGMP report in this period? */
if ((ip_ptr -> nx_ip_igmp_update_time[i] == 0) && (sent_count == 0))
{
/* Time has expired and we have not yet sent a packet out on this periodic. */
UINT index;
NX_INTERFACE *nx_interface = ip_ptr -> nx_ip_igmp_join_interface_list[i];
/* We need to find the interface this group address is on. */
for (index = 0; index < NX_MAX_PHYSICAL_INTERFACES; index++)
{
if (nx_interface == &(ip_ptr -> nx_ip_interface[index]))
{
/* Found it. */
interface_index = index;
break;
}
}
/* Build a IGMP host response packet for a join report and send it! */
status = _nx_igmp_interface_report_send(ip_ptr, *join_list_ptr, interface_index, NX_TRUE);
if (status == NX_SUCCESS)
{
/* Update the sent count. Only one report sent per IP periodic. */
sent_count++;
}
}
}
}
/* Move to the next entry in the join list. */
join_list_ptr++;
}
}

View File

@ -0,0 +1,103 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Group Management Protocol (IGMP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_igmp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_igmp_queue_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the IGMP receive packet queue. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_igmp_packet_process Process IGMP packet */
/* */
/* CALLED BY */
/* */
/* _nx_ip_thread_entry IP helper thread processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_igmp_queue_process(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_PACKET *queue_head;
NX_PACKET *packet_ptr;
/* Disable interrupts. */
TX_DISABLE
/* Remove the IGMP message queue from the IP structure. */
queue_head = ip_ptr -> nx_ip_igmp_queue_head;
ip_ptr -> nx_ip_igmp_queue_head = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Walk through the entire IGMP message queue and process packets
one by one. */
while (queue_head)
{
/* Pickup the first queue IGMP message and remove it from the
IGMP queue. */
packet_ptr = queue_head;
queue_head = queue_head -> nx_packet_queue_next;
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Process the packet. */
_nx_igmp_packet_process(ip_ptr, packet_ptr);
}
}

View File

@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_address_change_notify PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers an application callback routine that NetX */
/* calls whenever the IP address is changed. */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* ip_address_change_notify Application callback function */
/* additional_info Optional additional information */
/* for the callback function */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_address_change_notify(NX_IP *ip_ptr, VOID (*ip_address_change_notify)(NX_IP *, VOID *), VOID *additional_info)
{
TX_INTERRUPT_SAVE_AREA
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_ADDRESS_CHANGE_NOTIFY, ip_ptr, ip_address_change_notify, additional_info, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Disable interrupts. */
TX_DISABLE
/* Setup the IP address change callback function and the additional information pointers. */
ip_ptr -> nx_ip_address_change_notify = ip_address_change_notify;
ip_ptr -> nx_ip_address_change_notify_additional_info = additional_info;
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,95 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_address_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves the IP address and the network mask and */
/* returns them to the caller. */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* ip_address Pointer to IP address */
/* network_mask Pointer to network mask */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_address_get(NX_IP *ip_ptr, ULONG *ip_address, ULONG *network_mask)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Pickup the IP address and the network mask. */
*ip_address = ip_ptr -> nx_ip_interface[0].nx_interface_ip_address;
*network_mask = ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask;
/* Restore interrupts. */
TX_RESTORE
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_ADDRESS_GET, ip_ptr, ip_ptr -> nx_ip_interface[0].nx_interface_ip_address,
ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Return completion status. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,126 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_address_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets the IP address and the network mask for the */
/* supplied IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* ip_address IP address */
/* network_mask Network mask */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_address_set(NX_IP *ip_ptr, ULONG ip_address, ULONG network_mask)
{
TX_INTERRUPT_SAVE_AREA
VOID (*address_change_notify)(NX_IP *, VOID *);
VOID *additional_info;
ULONG previous_ip_address;
ULONG previous_network_mask;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_ADDRESS_SET, ip_ptr, ip_address, network_mask, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Disable interrupts. */
TX_DISABLE
/* Save previous IP address and network mask. */
previous_ip_address = ip_ptr -> nx_ip_interface[0].nx_interface_ip_address;
previous_network_mask = ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask;
/* Pickup the current notification callback and additional information pointers. */
address_change_notify = ip_ptr -> nx_ip_address_change_notify;
additional_info = ip_ptr -> nx_ip_address_change_notify_additional_info;
/* Setup the IP address and the network mask. */
ip_ptr -> nx_ip_interface[0].nx_interface_ip_address = ip_address;
ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask = network_mask;
ip_ptr -> nx_ip_interface[0].nx_interface_ip_network = ip_address & network_mask;
/* Ensure the RARP function is disabled. */
ip_ptr -> nx_ip_rarp_periodic_update = NX_NULL;
ip_ptr -> nx_ip_rarp_queue_process = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Determine if the application should be notified of the IP address and/or
network mask change. */
if ((address_change_notify) &&
((ip_address != previous_ip_address) || (network_mask != previous_network_mask)))
{
/* Yes, call the application's IP address change notify function. */
(address_change_notify)(ip_ptr, additional_info);
}
/* Initialize the ARP defend timeout. */
ip_ptr -> nx_ip_interface[0].nx_interface_arp_defend_timeout = 0;
/* Return completion status. */
return(NX_SUCCESS);
}

270
common/src/nx_ip_create.c Normal file
View File

@ -0,0 +1,270 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
#include "nx_system.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates an Internet Protocol instance, including */
/* setting up all appropriate data structures and calling the supplied */
/* link driver for initialization of the physical interface. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* name Name of this IP instance */
/* ip_address Internet address for this IP */
/* network_mask Network mask for IP address */
/* default_pool Default packet pool */
/* ip_link_driver User supplied IP link driver */
/* memory_ptr Pointer memory area for IP */
/* memory_size Size of IP memory area */
/* priority Priority of IP helper thread */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_event_flags_create Create IP event flags */
/* tx_event_flags_delete Delete IP event flags */
/* tx_mutex_create Create IP protection mutex */
/* tx_mutex_delete Delete IP protection mutex */
/* tx_thread_create Create IP helper thread */
/* tx_timer_create Create IP periodic timer */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_create(NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask,
NX_PACKET_POOL *default_pool, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *),
VOID *memory_ptr, ULONG memory_size, UINT priority)
{
TX_INTERRUPT_SAVE_AREA
NX_IP *tail_ptr;
/* Reference the version ID and option words to ensure they are linked in. */
if ((_nx_system_build_options_1 | _nx_system_build_options_2 | _nx_system_build_options_3 |
_nx_system_build_options_4 | _nx_system_build_options_5 | (ULONG)_nx_version_id[0]) == 0)
{
/* We should never get here! */
return(NX_NOT_IMPLEMENTED);
}
/* Initialize the IP control block to zero. */
memset((void *)ip_ptr, 0, sizeof(NX_IP));
ip_ptr -> nx_ip_interface[0].nx_interface_valid = 1;
/* Save the IP address. */
ip_ptr -> nx_ip_interface[0].nx_interface_ip_address = ip_address;
/* Save the network mask. */
ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask = network_mask;
/* Derive the network bits of this IP address. */
ip_ptr -> nx_ip_interface[0].nx_interface_ip_network = ip_address & network_mask;
/* Setup the link driver address. */
ip_ptr -> nx_ip_interface[0].nx_interface_link_driver_entry = ip_link_driver;
/* Set the device interface name to "PRI". */
ip_ptr -> nx_ip_interface[0].nx_interface_name = "PRI";
/* Store the IP instance into the interface structure. */
ip_ptr -> nx_ip_interface[0].nx_interface_ip_instance = ip_ptr;
/* Initialize the ARP defend timeout. */
ip_ptr -> nx_ip_interface[0].nx_interface_arp_defend_timeout = 0;
#ifndef NX_DISABLE_LOOPBACK_INTERFACE
/* Set the IP instance. */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_instance = ip_ptr;
/* Set the Loopback interface name. */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_name = "Internal IP Loopback";
/* Mark the loopback interface as valid. */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_valid = 1;
/* Set the loopback interface address. */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_address = 0x7F000001;
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_network_mask = 0xFF000000;
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_network = 0x7F000000;
/* Loopback interface is a special case. Therefore no dedicated link driver needed. */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_link_driver_entry = NX_NULL;
/* Loopback interface does not need IP/MAC address mapping. */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_address_mapping_needed = 0;
/* There is actually no MTU limit for the loopback interface. */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_mtu_size = 65535;
/* Mark the loopback interface as LINK UP */
ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_link_up = 1;
#endif /* !NX_DISABLE_LOOPBACK_INTERFACE */
/* Save the supplied IP name. */
ip_ptr -> nx_ip_name = name;
/* Set the initial IP packet ID. */
ip_ptr -> nx_ip_packet_id = NX_INIT_PACKET_ID;
/* Setup the default packet pool for this IP instance. */
ip_ptr -> nx_ip_default_packet_pool = default_pool;
/* Create the internal IP protection mutex. */
if (tx_mutex_create(&(ip_ptr -> nx_ip_protection), name, TX_NO_INHERIT))
{
return(NX_IP_INTERNAL_ERROR);
}
/* Create the internal IP event flag object. */
if (tx_event_flags_create(&(ip_ptr -> nx_ip_events), name))
{
/* Delete the internal mutex. */
tx_mutex_delete(&(ip_ptr -> nx_ip_protection));
/* Return an error. */
return(NX_IP_INTERNAL_ERROR);
}
/* Create the internal IP thread for handling more processing intensive
duties. */
if (tx_thread_create(&(ip_ptr -> nx_ip_thread), name, _nx_ip_thread_entry, (ULONG)ip_ptr,
memory_ptr, memory_size, priority, priority, 1, TX_AUTO_START))
{
/* Delete the event flag group. */
tx_event_flags_delete(&(ip_ptr -> nx_ip_events));
/* Delete the internal mutex. */
tx_mutex_delete(&(ip_ptr -> nx_ip_protection));
/* Return an error. */
return(NX_IP_INTERNAL_ERROR);
}
/* Create the periodic timer for this IP instance. */
if (tx_timer_create(&(ip_ptr -> nx_ip_periodic_timer), name,
_nx_ip_periodic_timer_entry, (ULONG)ip_ptr,
NX_IP_PERIODIC_RATE, NX_IP_PERIODIC_RATE, TX_AUTO_ACTIVATE))
{
/* Delete the event flag group. */
tx_event_flags_delete(&(ip_ptr -> nx_ip_events));
/* Delete the internal mutex. */
tx_mutex_delete(&(ip_ptr -> nx_ip_protection));
/* Terminate and delete helper thread. */
tx_thread_terminate(&(ip_ptr -> nx_ip_thread));
tx_thread_delete(&(ip_ptr -> nx_ip_thread));
/* Return an error. */
return(NX_IP_INTERNAL_ERROR);
}
/* If trace is enabled, register this object. */
NX_TRACE_OBJECT_REGISTER(NX_TRACE_OBJECT_TYPE_IP, ip_ptr, name, memory_ptr, memory_size)
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_CREATE, ip_ptr, ip_address, network_mask, default_pool, NX_TRACE_IP_EVENTS, 0, 0)
/* Otherwise, the IP initialization was successful. Place the
IP control block on the list of created IP instances. */
TX_DISABLE
/* Load the IP ID field in the IP control block. */
ip_ptr -> nx_ip_id = NX_IP_ID;
/* Place the new IP control block on the list of created IPs. First,
check for an empty list. */
if (_nx_ip_created_ptr)
{
/* Pickup tail pointer. */
tail_ptr = _nx_ip_created_ptr -> nx_ip_created_previous;
/* Place the new IP control block in the list. */
_nx_ip_created_ptr -> nx_ip_created_previous = ip_ptr;
tail_ptr -> nx_ip_created_next = ip_ptr;
/* Setup this IP's created links. */
ip_ptr -> nx_ip_created_previous = tail_ptr;
ip_ptr -> nx_ip_created_next = _nx_ip_created_ptr;
}
else
{
/* The created IP list is empty. Add IP control block to empty list. */
_nx_ip_created_ptr = ip_ptr;
ip_ptr -> nx_ip_created_next = ip_ptr;
ip_ptr -> nx_ip_created_previous = ip_ptr;
}
/* Increment the created IP counter. */
_nx_ip_created_count++;
/* Restore previous interrupt posture. */
TX_RESTORE
/* Return success to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,102 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_diferred_link_status_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes link status change event. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* link_driver_entry Link driver */
/* */
/* CALLED BY */
/* */
/* nx_ip_thread_entry */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_deferred_link_status_process(NX_IP *ip_ptr)
{
UINT i;
NX_IP_DRIVER driver_request;
ULONG link_up;
if (ip_ptr -> nx_ip_link_status_change_callback == NX_NULL)
{
/* Callback function is not set. */
return;
}
for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
{
if ((ip_ptr -> nx_ip_interface[i].nx_interface_valid) &&
(ip_ptr -> nx_ip_interface[i].nx_interface_link_status_change))
{
/* Reset the flag. */
ip_ptr -> nx_ip_interface[i].nx_interface_link_status_change = NX_FALSE;
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_GET_STATUS;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[i]);
driver_request.nx_ip_driver_return_ptr = &link_up;
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
/* Invoke the callback function. */
ip_ptr -> nx_ip_link_status_change_callback(ip_ptr, i, link_up);
}
}
}

336
common/src/nx_ip_delete.c Normal file
View File

@ -0,0 +1,336 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
#include "nx_icmp.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_delete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deletes an Internet Protocol instance, including */
/* calling the associated driver with a link disable request. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_ip_delete_queue_clear Clear a packet queue */
/* _nx_ip_raw_packet_cleanup Cleanup raw packet suspension */
/* _nx_icmp_cleanup Cleanup for ICMP packets */
/* _nx_ip_fragment_disable Disable fragment processing */
/* tx_mutex_delete Delete IP protection mutex */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* tx_thread_terminate Terminate IP helper thread */
/* tx_event_flags_delete Delete IP event flags */
/* tx_thread_delete Delete IP helper thread */
/* _tx_thread_system_preempt_check Check for preemption */
/* tx_timer_deactivate Deactivate IP-ARP timer */
/* tx_timer_delete Delete IP-ARP timer */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_delete(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_IP_DRIVER driver_request;
NX_PACKET *raw_packet_head;
NX_PACKET *deferred_head;
NX_PACKET *icmp_queue_head;
NX_PACKET *igmp_queue_head;
NX_PACKET *tcp_queue_head;
NX_PACKET *arp_queue_head;
NX_PACKET *rarp_queue_head;
UINT i;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_DELETE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Determine if the IP instance has any sockets bound to it. */
if ((ip_ptr -> nx_ip_udp_created_sockets_count) || (ip_ptr -> nx_ip_tcp_created_sockets_count))
{
/* Still sockets bound to this IP instance. They must all be deleted prior
to deleting the IP instance. Release the mutex and return
an error code. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
return(NX_SOCKETS_BOUND);
}
/* Call through every link driver to disable the link. */
for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
{
/* Skip the invalid entries. */
if (!(ip_ptr -> nx_ip_interface[i].nx_interface_valid))
{
continue;
}
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_DISABLE;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[i]);
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_LINK_DISABLE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry) (&driver_request);
/* Call the link driver to uninitialize. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_UNINITIALIZE;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_UNINITIALIZE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry) (&driver_request);
}
/* Disable interrupts. */
TX_DISABLE
/* Remove the IP instance from the created list. */
/* See if the IP instance is the only one on the list. */
if (ip_ptr == ip_ptr -> nx_ip_created_next)
{
/* Only created IP instance, just set the created list to NULL. */
_nx_ip_created_ptr = TX_NULL;
}
else
{
/* Otherwise, not the only created IP, link-up the neighbors. */
(ip_ptr -> nx_ip_created_next) -> nx_ip_created_previous =
ip_ptr -> nx_ip_created_previous;
(ip_ptr -> nx_ip_created_previous) -> nx_ip_created_next =
ip_ptr -> nx_ip_created_next;
/* See if we have to update the created list head pointer. */
if (_nx_ip_created_ptr == ip_ptr)
{
/* Yes, move the head pointer to the next link. */
_nx_ip_created_ptr = ip_ptr -> nx_ip_created_next;
}
}
/* Decrement the IP created counter. */
_nx_ip_created_count--;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Release any raw packets queued up. */
raw_packet_head = ip_ptr -> nx_ip_raw_received_packet_head;
ip_ptr -> nx_ip_raw_received_packet_head = NX_NULL;
ip_ptr -> nx_ip_raw_received_packet_tail = NX_NULL;
ip_ptr -> nx_ip_raw_received_packet_count = 0;
/* Release all deferred IP packets. */
deferred_head = ip_ptr -> nx_ip_deferred_received_packet_head;
ip_ptr -> nx_ip_deferred_received_packet_head = NX_NULL;
ip_ptr -> nx_ip_deferred_received_packet_tail = NX_NULL;
/* Release all queued ICMP packets. */
icmp_queue_head = ip_ptr -> nx_ip_icmp_queue_head;
ip_ptr -> nx_ip_icmp_queue_head = NX_NULL;
/* Release all queued IGMP packets. */
igmp_queue_head = ip_ptr -> nx_ip_igmp_queue_head;
ip_ptr -> nx_ip_igmp_queue_head = NX_NULL;
/* Release all queued TCP packets. */
tcp_queue_head = ip_ptr -> nx_ip_tcp_queue_head;
ip_ptr -> nx_ip_tcp_queue_head = NX_NULL;
ip_ptr -> nx_ip_tcp_queue_tail = NX_NULL;
/* Release all queued ARP packets. */
arp_queue_head = ip_ptr -> nx_ip_arp_deferred_received_packet_head;
ip_ptr -> nx_ip_arp_deferred_received_packet_head = NX_NULL;
ip_ptr -> nx_ip_arp_deferred_received_packet_tail = NX_NULL;
/* Release all queued RARP packets. */
rarp_queue_head = ip_ptr -> nx_ip_rarp_deferred_received_packet_head;
ip_ptr -> nx_ip_rarp_deferred_received_packet_head = NX_NULL;
ip_ptr -> nx_ip_rarp_deferred_received_packet_tail = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Deactivate and delete the IP periodic timer. */
tx_timer_deactivate(&(ip_ptr -> nx_ip_periodic_timer));
tx_timer_delete(&(ip_ptr -> nx_ip_periodic_timer));
/* Determine if TCP is enabled. */
if (ip_ptr -> nx_ip_tcp_packet_receive)
{
/* Yes, TCP is enabled. Deactivate and delete the TCP fast periodic timer. */
tx_timer_deactivate(&(ip_ptr -> nx_ip_tcp_fast_periodic_timer));
tx_timer_delete(&(ip_ptr -> nx_ip_tcp_fast_periodic_timer));
}
/* Terminate the internal IP thread. */
tx_thread_terminate(&(ip_ptr -> nx_ip_thread));
/* Delete the internal IP protection mutex. */
tx_mutex_delete(&(ip_ptr -> nx_ip_protection));
/* Delete the internal IP event flag object. */
tx_event_flags_delete(&(ip_ptr -> nx_ip_events));
/* Delete the internal IP thread for handling more processing intensive
duties. */
tx_thread_delete(&(ip_ptr -> nx_ip_thread));
/* Release any raw packets queued up. */
if (raw_packet_head)
{
_nx_ip_delete_queue_clear(raw_packet_head);
}
/* Release any deferred IP packets. */
if (deferred_head)
{
_nx_ip_delete_queue_clear(deferred_head);
}
/* Release any queued ICMP packets. */
if (icmp_queue_head)
{
_nx_ip_delete_queue_clear(icmp_queue_head);
}
/* Release any queued IGMP packets. */
if (igmp_queue_head)
{
_nx_ip_delete_queue_clear(igmp_queue_head);
}
/* Release any queued TCP packets. */
if (tcp_queue_head)
{
_nx_ip_delete_queue_clear(tcp_queue_head);
}
/* Release any queued ARP packets. */
if (arp_queue_head)
{
_nx_ip_delete_queue_clear(arp_queue_head);
}
/* Release any queued RARP packets. */
if (rarp_queue_head)
{
_nx_ip_delete_queue_clear(rarp_queue_head);
}
/* Lift any suspension on RAW IP packet receives. */
while (ip_ptr -> nx_ip_raw_packet_suspension_list)
{
/* Release the suspended thread. */
_nx_ip_raw_packet_cleanup(ip_ptr -> nx_ip_raw_packet_suspension_list NX_CLEANUP_ARGUMENT);
}
/* Lift any suspension on ICMP ping requests. */
while (ip_ptr -> nx_ip_icmp_ping_suspension_list)
{
/* Release the suspended thread. */
_nx_icmp_cleanup(ip_ptr -> nx_ip_icmp_ping_suspension_list NX_CLEANUP_ARGUMENT);
}
/* Determine if fragment processing was enabled. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Yes, disable fragment processing, which will release all outstanding
fragmented packets. */
_nx_ip_fragment_disable(ip_ptr);
}
/* Clear the IP ID to make it invalid. */
ip_ptr -> nx_ip_id = 0;
/* Disable interrupts. */
TX_DISABLE
/* Restore preemption. */
_tx_thread_preempt_disable--;
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
/* Return success to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,94 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_delete_queue_clear PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function releases all packets in a packet queue. */
/* */
/* INPUT */
/* */
/* head_ptr Pointer to head of queue */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_packet_release Release data packet */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_delete_queue_clear(NX_PACKET *head_ptr)
{
NX_PACKET *next_packet;
NX_PACKET *current_packet;
/* Setup next packet to queue head. */
next_packet = head_ptr;
/* Release any raw IP packets queued up. */
while (next_packet)
{
/* Setup the current packet pointer. */
current_packet = next_packet;
/* Move to the next packet. */
next_packet = next_packet -> nx_packet_queue_next;
/* Release the current packet. */
_nx_packet_release(current_packet);
}
}

View File

@ -0,0 +1,98 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_driver_deferred_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enabled the deferred driver packet processing */
/* in NetX. The supplied driver packet handler is called from the */
/* IP helper thread to fully process a received driver packet. The */
/* driver's receive packet processing only makes a call to the */
/* _nx_ip_driver_deferred_receive processing from the ISR. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* driver_deferred_packet_handler Function pointer to driver's */
/* deferred packet handling */
/* routine */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Driver Initialization */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_driver_deferred_enable(NX_IP *ip_ptr, VOID (*driver_deferred_packet_handler)(NX_IP *ip_ptr, NX_PACKET *packet_ptr))
{
#ifdef NX_DRIVER_DEFERRED_PROCESSING
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Initialize the deferred packet queue to be empty */
ip_ptr -> nx_ip_driver_deferred_packet_head = NX_NULL;
ip_ptr -> nx_ip_driver_deferred_packet_tail = NX_NULL;
/* Setup the driver's deferred packet processing routine */
ip_ptr -> nx_ip_driver_deferred_packet_handler = driver_deferred_packet_handler;
TX_RESTORE
#else
NX_PARAMETER_NOT_USED(ip_ptr);
NX_PARAMETER_NOT_USED(driver_deferred_packet_handler);
#endif
}

View File

@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_driver_deferred_processing PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function causes the driver to be called from the IP helper */
/* thread in order to finish some deferred processing. A typical */
/* example of this is the transmit complete interrupt. Instead of */
/* loading the packet inside the transmit complete interrupt, the */
/* driver can setup some internal variables and call this routine */
/* to be called subsequently from the IP helper thread to finish */
/* the transmit complete interrupt processing. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* tx_event_flags_set Set event flags to wake IP */
/* helper thread */
/* */
/* CALLED BY */
/* */
/* Application Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_driver_deferred_processing(NX_IP *ip_ptr)
{
/* Set event flags to wake the IP helper thread, which will in turn
call the driver with the NX_LINK_DEFERRED_PROCESSING command. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_DRIVER_DEFERRED_EVENT, TX_OR);
}

View File

@ -0,0 +1,118 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_driver_deferred_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function places the supplied packet on the driver's deferred */
/* receive queue. It will be processed later during subsequent */
/* execution of the IP helper thread by calling the driver's deferred */
/* handling routine. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Raw receive packet */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Driver Receive ISR */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_driver_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
#ifdef NX_DRIVER_DEFERRED_PROCESSING
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Add the packet to the end of the driver queue for processing */
packet_ptr -> nx_packet_queue_next = NX_NULL;
if (ip_ptr -> nx_ip_driver_deferred_packet_head == NX_NULL)
{
/* The queue is empty, set both the first and last packet
pointers to the new packet */
ip_ptr -> nx_ip_driver_deferred_packet_head = packet_ptr;
ip_ptr -> nx_ip_driver_deferred_packet_tail = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
/* Wakeup IP helper thread to process the packet. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_DRIVER_PACKET_EVENT, TX_OR);
}
else
{
/* The queue is not empty, simply add the packet to the end of the queue. */
(ip_ptr -> nx_ip_driver_deferred_packet_tail) -> nx_packet_queue_next = packet_ptr;
ip_ptr -> nx_ip_driver_deferred_packet_tail = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
}
#else
NX_PARAMETER_NOT_USED(ip_ptr);
/* No deferred packet processing, just release the packet. */
_nx_packet_release(packet_ptr);
#endif
}

View File

@ -0,0 +1,108 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_driver_direct_command PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function provides the application with direct access to the */
/* IP's link-level driver. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* command Driver command (NX_LINK_*) */
/* return_value_ptr Pointer to place return values*/
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_driver_direct_command(NX_IP *ip_ptr, UINT command, ULONG *return_value_ptr)
{
NX_IP_DRIVER driver_request;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *trace_event;
ULONG trace_timestamp;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_DRIVER_DIRECT_COMMAND, ip_ptr, command, 0, 0, NX_TRACE_IP_EVENTS, &trace_event, &trace_timestamp)
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Build the driver request structure. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = command;
driver_request.nx_ip_driver_return_ptr = return_value_ptr;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[0]);
(ip_ptr -> nx_ip_interface[0].nx_interface_link_driver_entry)(&driver_request);
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_IP_DRIVER_DIRECT_COMMAND, 0, 0, driver_request.nx_ip_driver_status, 0)
/* Return status to the caller. */
return(driver_request.nx_ip_driver_status);
}

View File

@ -0,0 +1,108 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_driver_interface_direct_command PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function provides the application with direct access to */
/* the specific IP's link-level driver. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* command Driver command (NX_LINK_*) */
/* interface_index Index to the interface */
/* return_value_ptr Pointer to place return values*/
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_driver_interface_direct_command(NX_IP *ip_ptr, UINT command, UINT interface_index, ULONG *return_value_ptr)
{
NX_IP_DRIVER driver_request;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *trace_event;
ULONG trace_timestamp;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_DRIVER_DIRECT_COMMAND, ip_ptr, command, 0, 0, NX_TRACE_IP_EVENTS, &trace_event, &trace_timestamp)
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Build the driver request structure. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = command;
driver_request.nx_ip_driver_return_ptr = return_value_ptr;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
(ip_ptr -> nx_ip_interface[interface_index].nx_interface_link_driver_entry)(&driver_request);
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_IP_DRIVER_DIRECT_COMMAND, 0, 0, driver_request.nx_ip_driver_status, 0)
/* Return status to the caller. */
return(driver_request.nx_ip_driver_status);
}

View File

@ -0,0 +1,85 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_driver_link_status_event PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deferrs link status event from ISR to the IP helper */
/* thread. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* interface_index Index of interface */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* tx_event_flags_set Wakeup IP helper thread */
/* */
/* CALLED BY */
/* */
/* Application I/O Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_driver_link_status_event(NX_IP *ip_ptr, UINT interface_index)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Mark link status changed. */
ip_ptr -> nx_ip_interface[interface_index].nx_interface_link_status_change = NX_TRUE;
/* Wakeup IP helper thread to process the link status event. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_LINK_STATUS_EVENT, TX_OR);
/* Restore interrupts. */
TX_RESTORE
}

View File

@ -0,0 +1,97 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_packet_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function attempts to forward the IP packet to the destination */
/* IP by using the NetX send packet routine. Note that the IP header */
/* is still intact prior to the packet. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to forward */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_ip_packet_send Send IP packet */
/* */
/* CALLED BY */
/* */
/* _nx_ip_packet_receive Receive IP packet */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_forward_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
NX_IP_HEADER *ip_header_ptr;
/* The NetX IP forwarding consists of simply sending the same packet out through
the internal send routine. Applications may choose to modify this code or
replace the nx_ip_forward_packet_process pointer in the IP structure to point
at an application-specific routine for forwarding. */
/* It's assumed that the IP header is still present in front of the packet. Position
backwards to access it. */
ip_header_ptr = (NX_IP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IP_HEADER));
/* Call the IP send routine to forward the packet. */
_nx_ip_packet_send(ip_ptr, packet_ptr, ip_header_ptr -> nx_ip_header_destination_ip,
(ip_header_ptr -> nx_ip_header_word_0 & NX_IP_TOS_MASK),
(ip_header_ptr -> nx_ip_header_word_2 & NX_IP_TIME_TO_LIVE_MASK) >> NX_IP_TIME_TO_LIVE_SHIFT,
(ip_header_ptr -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK),
(ip_header_ptr -> nx_ip_header_word_1 & NX_DONT_FRAGMENT));
/* Return to caller. */
return;
}

View File

@ -0,0 +1,91 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_forwarding_disable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function disables the IP forwarding by clearing the forward */
/* processing function pointer in the specified IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_forwarding_disable(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_FORWARDING_DISABLE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Disable interrupts temporarily. */
TX_DISABLE
/* Clear the IP forwarding processing routine pointer. */
ip_ptr -> nx_ip_forward_packet_process = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Return success to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,91 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_forwarding_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enables the IP forwarding by setting up the forward */
/* processing function pointer in the specified IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_forwarding_enable(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_FORWARDING_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Disable interrupts temporarily. */
TX_DISABLE
/* Setup the IP forwarding processing routine pointer. */
ip_ptr -> nx_ip_forward_packet_process = _nx_ip_forward_packet_process;
/* Restore interrupts. */
TX_RESTORE
/* Return success to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,481 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_fragment_assemble PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes the received fragment queue and attempts to */
/* reassemble fragmented IP datagrams. Once a datagram is reassembled */
/* it is dispatched to the appropriate component. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_packet_release Release packet */
/* (ip_tcp_packet_receive) Receive a TCP packet */
/* (ip_udp_packet_receive) Receive a UDP packet */
/* (ip_icmp_packet_receive) Receive a ICMP packet */
/* (ip_igmp_packet_receive) Receive a IGMP packet */
/* (ip_raw_ip_raw_packet_processing) Process a Raw IP packet */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_fragment_assembly(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_PACKET *new_fragment_head;
NX_PACKET *current_fragment;
NX_PACKET *previous_fragment = NX_NULL;
NX_PACKET *fragment_head;
NX_PACKET *search_ptr;
NX_PACKET *previous_ptr;
NX_PACKET *found_ptr;
NX_IP_HEADER *search_header;
NX_IP_HEADER *current_header;
ULONG current_id;
ULONG current_offset;
ULONG protocol;
UCHAR incomplete;
/* Disable interrupts. */
TX_DISABLE
/* Remove the packets from the incoming IP fragment queue. */
new_fragment_head = ip_ptr -> nx_ip_received_fragment_head;
ip_ptr -> nx_ip_received_fragment_head = NX_NULL;
ip_ptr -> nx_ip_received_fragment_tail = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Process each IP packet in the received IP fragment queue. */
while (new_fragment_head)
{
/* Setup the current fragment pointer. */
current_fragment = new_fragment_head;
/* Move the head pointer. */
new_fragment_head = new_fragment_head -> nx_packet_queue_next;
/* Setup header pointer for this packet. */
current_header = (NX_IP_HEADER *)current_fragment -> nx_packet_prepend_ptr;
/* Pickup the ID of this fragment. */
current_id = (current_header -> nx_ip_header_word_1 >> NX_SHIFT_BY_16);
/* Set the found pointer to NULL. */
found_ptr = NX_NULL;
/* Does the assembly list have anything in it? */
if (ip_ptr -> nx_ip_fragment_assembly_head)
{
/* Yes, we need to search the assembly queue to see if this fragment belongs
to another fragment. */
search_ptr = ip_ptr -> nx_ip_fragment_assembly_head;
previous_fragment = NX_NULL;
while (search_ptr)
{
/* Setup a pointer to the IP header of the packet in the assembly list. */
search_header = (NX_IP_HEADER *)search_ptr -> nx_packet_prepend_ptr;
/* Determine if the IP header fields match. RFC 791 Section 3.2 recommends that packet
fragments be compared for source IP, destination IP, protocol and IP header ID. */
if ((current_id == (search_header -> nx_ip_header_word_1 >> NX_SHIFT_BY_16)) &&
((search_header -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK) ==
(current_header -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK)) &&
(search_header -> nx_ip_header_source_ip == current_header -> nx_ip_header_source_ip) &&
(search_header -> nx_ip_header_destination_ip == current_header -> nx_ip_header_destination_ip))
{
/* Yes, we found a match, just set the found_ptr and get out of
this loop! */
found_ptr = search_ptr;
break;
}
/* Remember the previous pointer. */
previous_fragment = search_ptr;
/* Move to the next IP fragment in the re-assembly queue. */
search_ptr = search_ptr -> nx_packet_queue_next;
}
}
/* Was another IP packet fragment found? */
if (found_ptr)
{
/* Save the fragment head pointer. */
fragment_head = found_ptr;
/* Pickup the offset of the new IP fragment. */
current_offset = current_header -> nx_ip_header_word_1 & NX_IP_OFFSET_MASK;
/* Another packet fragment was found... find the proper place in the list
for this packet and check for complete re-assembly. */
/* Setup the previous pointer. Note that the search pointer still points
to the first fragment in the list. */
previous_ptr = NX_NULL;
search_ptr = found_ptr;
/* Loop to walk through the fragment list. */
do
{
/* Pickup a pointer to the IP header of the fragment. */
search_header = (NX_IP_HEADER *)search_ptr -> nx_packet_prepend_ptr;
/* Determine if the incoming IP fragment goes before this packet. */
if (current_offset < (search_header -> nx_ip_header_word_1 & NX_IP_OFFSET_MASK))
{
/* Yes, break out of the loop and insert the current packet. */
break;
}
/* Otherwise, move the search and previous pointers to the next fragment in the
chain. */
previous_ptr = search_ptr;
search_ptr = search_ptr -> nx_packet_fragment_next;
} while (search_ptr);
/* At this point, the previous pointer determines where to place the new fragment. */
if (previous_ptr)
{
/* Add new fragment after the previous ptr. */
current_fragment -> nx_packet_fragment_next = previous_ptr -> nx_packet_fragment_next;
previous_ptr -> nx_packet_fragment_next = current_fragment;
}
else
{
/* This packet needs to be inserted at the front of the fragment chain. */
current_fragment -> nx_packet_queue_next = fragment_head -> nx_packet_queue_next;
current_fragment -> nx_packet_fragment_next = fragment_head;
if (previous_fragment)
{
/* We need to link up a different IP packet fragment chain that is in
front of this one on the re-assembly queue. */
previous_fragment -> nx_packet_queue_next = current_fragment;
}
else
{
/* Nothing prior to this IP fragment chain, we need to just change the
list header. */
ip_ptr -> nx_ip_fragment_assembly_head = current_fragment;
/* Clear the timeout fragment pointer. */
ip_ptr -> nx_ip_timeout_fragment = NX_NULL;
}
/* Determine if we need to adjust the tail pointer. */
if (fragment_head == ip_ptr -> nx_ip_fragment_assembly_tail)
{
/* Setup the new tail pointer. */
ip_ptr -> nx_ip_fragment_assembly_tail = current_fragment;
}
/* Setup the new fragment head. */
fragment_head = current_fragment;
}
/* At this point, the new IP fragment is in its proper place on the re-assembly
list. We now need to walk the list and determine if all the fragments are
present. */
/* Setup the search pointer to the fragment head. */
search_ptr = fragment_head;
/* Set the current expected offset to 0. */
current_offset = 0;
/* Loop through the packet chain to see if all the fragments have
arrived. */
incomplete = 0;
do
{
/* Build the IP header pointer. */
search_header = (NX_IP_HEADER *)search_ptr -> nx_packet_prepend_ptr;
/* Check for the expected current offset. */
if (current_offset != (search_header -> nx_ip_header_word_1 & NX_IP_OFFSET_MASK))
{
/* There are still more fragments necessary to reassemble this packet
so just return. */
incomplete = 1;
break;
}
/* Calculate the next expected offset. */
current_offset = current_offset +
((search_header -> nx_ip_header_word_0 & NX_LOWER_16_MASK) - sizeof(NX_IP_HEADER)) / NX_IP_ALIGN_FRAGS;
/* Move the search pointer forward to the next fragment. */
search_ptr = search_ptr -> nx_packet_fragment_next;
} while (search_ptr);
if (incomplete)
{
continue;
}
/* At this point the search header points to the last fragment in the chain. In
order for the packet to be complete, the "more fragments" bit in its IP header
must be clear. */
if (search_header -> nx_ip_header_word_1 & NX_IP_MORE_FRAGMENT)
{
/* There are still more fragments necessary to re-assembly this packet
so just return. */
continue;
}
/* If we get here, the necessary fragments to reassemble the packet
are indeed available. We now need to loop through the packet and reassemble
it. */
search_ptr = fragment_head -> nx_packet_fragment_next;
/* Loop through the fragments and assemble the IP fragment. */
while (search_ptr)
{
/* Accumulate the new length into the head packet. */
fragment_head -> nx_packet_length = fragment_head -> nx_packet_length +
search_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
/* Position past the IP header in the subsequent packets. */
search_ptr -> nx_packet_prepend_ptr = search_ptr -> nx_packet_prepend_ptr +
sizeof(NX_IP_HEADER);
/* Link the addition fragment to the head fragment. */
if (fragment_head -> nx_packet_last)
{
(fragment_head -> nx_packet_last) -> nx_packet_next = search_ptr;
}
else
{
fragment_head -> nx_packet_next = search_ptr;
}
if (search_ptr -> nx_packet_last)
{
fragment_head -> nx_packet_last = search_ptr -> nx_packet_last;
}
else
{
fragment_head -> nx_packet_last = search_ptr;
}
/* Move to the next fragment in the chain. */
search_ptr = search_ptr -> nx_packet_fragment_next;
}
/* The packet is now reassembled under the fragment head pointer. It must now
be removed from the re-assembly list. */
if (previous_fragment)
{
/* Remove the fragment from a position other than the head of the assembly list. */
previous_fragment -> nx_packet_queue_next = fragment_head -> nx_packet_queue_next;
}
else
{
/* Modify the head of the re-assembly list. */
ip_ptr -> nx_ip_fragment_assembly_head = fragment_head -> nx_packet_queue_next;
/* Clear the timeout fragment pointer since we are removing the first
fragment (the oldest) on the assembly list. */
ip_ptr -> nx_ip_timeout_fragment = NX_NULL;
}
/* Determine if we need to adjust the tail pointer. */
if (fragment_head == ip_ptr -> nx_ip_fragment_assembly_tail)
{
/* Setup the new tail pointer. */
ip_ptr -> nx_ip_fragment_assembly_tail = previous_fragment;
}
/* We are now ready to dispatch this packet just like the normal IP receive packet
processing. */
/* Build a pointer to the IP header. */
current_header = (NX_IP_HEADER *)fragment_head -> nx_packet_prepend_ptr;
/* Determine what protocol the current IP datagram is. */
protocol = current_header -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK;
/* Remove the IP header from the packet. */
fragment_head -> nx_packet_prepend_ptr = fragment_head -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER);
/* Adjust the length. */
fragment_head -> nx_packet_length = fragment_head -> nx_packet_length - sizeof(NX_IP_HEADER);
#ifndef NX_DISABLE_IP_INFO
/* Increment the number of packets reassembled. */
ip_ptr -> nx_ip_packets_reassembled++;
/* Increment the number of packets delivered. */
ip_ptr -> nx_ip_total_packets_delivered++;
/* Increment the IP packet bytes received (not including the header). */
ip_ptr -> nx_ip_total_bytes_received += fragment_head -> nx_packet_length;
#endif
/* Determine if RAW IP is supported. */
if (ip_ptr -> nx_ip_raw_ip_processing)
{
/* Call the raw IP packet processing routine. */
(ip_ptr -> nx_ip_raw_ip_processing)(ip_ptr, fragment_head);
}
/* Dispatch the protocol... Have we found a UDP packet? */
else if ((protocol == NX_IP_UDP) && (ip_ptr -> nx_ip_udp_packet_receive))
{
/* Yes, a UDP packet is present, dispatch to the appropriate UDP handler
if present. */
(ip_ptr -> nx_ip_udp_packet_receive)(ip_ptr, fragment_head);
}
/* Is a TCP packet present? */
else if ((protocol == NX_IP_TCP) && (ip_ptr -> nx_ip_tcp_packet_receive))
{
/* Yes, a TCP packet is present, dispatch to the appropriate TCP handler
if present. */
(ip_ptr -> nx_ip_tcp_packet_receive)(ip_ptr, fragment_head);
}
/* Is a ICMP packet present? */
else if ((protocol == NX_IP_ICMP) && (ip_ptr -> nx_ip_icmp_packet_receive))
{
/* Yes, a ICMP packet is present, dispatch to the appropriate ICMP handler
if present. */
(ip_ptr -> nx_ip_icmp_packet_receive)(ip_ptr, fragment_head);
}
else if ((protocol == NX_IP_IGMP) && (ip_ptr -> nx_ip_igmp_packet_receive))
{
/* Yes, a IGMP packet is present, dispatch to the appropriate ICMP handler
if present. */
(ip_ptr -> nx_ip_igmp_packet_receive)(ip_ptr, fragment_head);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Decrement the number of packets delivered. */
ip_ptr -> nx_ip_total_packets_delivered--;
/* Decrement the IP packet bytes received (not including the header). */
ip_ptr -> nx_ip_total_bytes_received -= fragment_head -> nx_packet_length;
/* Increment the IP unknown protocol count. */
ip_ptr -> nx_ip_unknown_protocols_received++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Toss the IP packet since we don't know what to do with it! */
_nx_packet_release(fragment_head);
}
}
else
{
/* No other packet was found on the re-assembly list so this packet must be the
first one of a new IP packet. Just add it to the end of the assembly queue. */
if (ip_ptr -> nx_ip_fragment_assembly_head)
{
/* Re-assembly list is not empty. Just place this IP packet at the
end of the IP fragment assembly list. */
ip_ptr -> nx_ip_fragment_assembly_tail -> nx_packet_queue_next = current_fragment;
ip_ptr -> nx_ip_fragment_assembly_tail = current_fragment;
current_fragment -> nx_packet_queue_next = NX_NULL;
current_fragment -> nx_packet_fragment_next = NX_NULL;
}
else
{
/* First IP fragment on the assembly list. Setup the head and tail pointers to
this packet. */
ip_ptr -> nx_ip_fragment_assembly_head = current_fragment;
ip_ptr -> nx_ip_fragment_assembly_tail = current_fragment;
current_fragment -> nx_packet_queue_next = NX_NULL;
current_fragment -> nx_packet_fragment_next = NX_NULL;
}
}
}
}

View File

@ -0,0 +1,157 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_fragment_disable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function disables IP fragment assembly processing and releases */
/* all partial fragments being assembled. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_packet_release Release packet */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_fragment_disable(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_PACKET *new_fragment_head;
NX_PACKET *assemble_head;
NX_PACKET *next_packet;
NX_PACKET *release_packet;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_FRAGMENT_DISABLE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Disable interrupts temporarily. */
TX_DISABLE
/* Clear the IP fragment processing routine pointer. */
ip_ptr -> nx_ip_fragment_processing = NX_NULL;
/* Clear the IP fragment assembly routine pointer. */
ip_ptr -> nx_ip_fragment_assembly = NX_NULL;
/* Clear the IP fragment timeout routine pointer. */
ip_ptr -> nx_ip_fragment_timeout_check = NX_NULL;
/* Pickup the fragment list pointer. */
new_fragment_head = ip_ptr -> nx_ip_received_fragment_head;
assemble_head = ip_ptr -> nx_ip_fragment_assembly_head;
/* Clear the IP structure lists. */
ip_ptr -> nx_ip_received_fragment_head = NX_NULL;
ip_ptr -> nx_ip_received_fragment_tail = NX_NULL;
ip_ptr -> nx_ip_fragment_assembly_head = NX_NULL;
ip_ptr -> nx_ip_fragment_assembly_tail = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Now walk through the receive and assembly lists to free the packets. */
next_packet = new_fragment_head;
while (next_packet)
{
/* Set the release packet to this packet. */
release_packet = next_packet;
/* Move next packet to the next in the list. */
next_packet = next_packet -> nx_packet_queue_next;
/* Release the current packet. */
_nx_packet_release(release_packet);
}
/* Now walk through the assemble list and release all packets. */
while (assemble_head)
{
/* Walk through the list of packets being assembled for this packet and release them. */
next_packet = assemble_head;
assemble_head = next_packet -> nx_packet_queue_next;
while (next_packet)
{
/* Set the release packet to this packet. */
release_packet = next_packet;
/* Move next packet to the next in the list. */
next_packet = next_packet -> nx_packet_fragment_next;
/* Release the current packet. */
_nx_packet_release(release_packet);
}
}
/* Return success to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,98 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_fragment_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enables the IP fragment processing by setting up the */
/* function pointers responsible for fragmenting and unfragmenting IP */
/* packets. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_fragment_enable(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_FRAGMENT_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Disable interrupts temporarily. */
TX_DISABLE
/* Setup the IP fragment processing routine pointer. */
ip_ptr -> nx_ip_fragment_processing = _nx_ip_fragment_packet;
/* Setup the IP fragment assembly routine pointer. */
ip_ptr -> nx_ip_fragment_assembly = _nx_ip_fragment_assembly;
/* Setup the IP fragment timeout routine pointer. */
ip_ptr -> nx_ip_fragment_timeout_check = _nx_ip_fragment_timeout_check;
/* Restore interrupts. */
TX_RESTORE
/* Return success to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,351 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_fragment_packet PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function breaks the supplied packet into fragments and sends */
/* them out through the associated IP driver. This function uses the */
/* already built IP header and driver request structure for each */
/* packet fragment. */
/* */
/* INPUT */
/* */
/* driver_req_ptr Pointer to driver request */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_packet_allocate Allocate packet for fragment */
/* _nx_packet_transmit_release Transmit packet release */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* _nx_arp_packet_receive Received ARP packet processing*/
/* _nx_ip_packet_send Send an IP packet */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_fragment_packet(struct NX_IP_DRIVER_STRUCT *driver_req_ptr)
{
UINT status;
#ifndef NX_DISABLE_IP_TX_CHECKSUM
ULONG checksum;
ULONG temp;
#endif /* NX_DISABLE_IP_TX_CHECKSUM */
UCHAR *source_ptr;
ULONG remaining_bytes;
ULONG fragment_size;
ULONG copy_size;
ULONG copy_remaining_size;
ULONG fragment_offset = 0;
NX_IP_DRIVER driver_request;
NX_PACKET *source_packet;
NX_PACKET *fragment_packet;
NX_IP_HEADER *source_header_ptr;
NX_IP_HEADER *fragment_header_ptr;
NX_IP *ip_ptr;
/* Setup the local driver request packet that will be used for each
fragment. There will be a unique packet pointer for each request, but
otherwise all the other fields will remain constant. */
driver_request = *driver_req_ptr;
/* Setup the IP pointer. */
ip_ptr = driver_req_ptr -> nx_ip_driver_ptr;
#ifndef NX_DISABLE_IP_INFO
/* Increment the total number of fragment requests. */
ip_ptr -> nx_ip_total_fragment_requests++;
#endif
/* Pickup the source packet pointer. */
source_packet = driver_req_ptr -> nx_ip_driver_packet;
/* Build a pointer to the source IP header. */
source_header_ptr = (NX_IP_HEADER *)source_packet -> nx_packet_prepend_ptr;
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the IP header. */
NX_CHANGE_ULONG_ENDIAN(source_header_ptr -> nx_ip_header_word_0);
NX_CHANGE_ULONG_ENDIAN(source_header_ptr -> nx_ip_header_word_1);
NX_CHANGE_ULONG_ENDIAN(source_header_ptr -> nx_ip_header_word_2);
NX_CHANGE_ULONG_ENDIAN(source_header_ptr -> nx_ip_header_source_ip);
NX_CHANGE_ULONG_ENDIAN(source_header_ptr -> nx_ip_header_destination_ip);
/* Pickup the length of the packet and the starting pointer. */
remaining_bytes = source_packet -> nx_packet_length - sizeof(NX_IP_HEADER);
source_ptr = source_packet -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER);
/* Derive the fragment size. */
fragment_size = source_packet -> nx_packet_ip_interface -> nx_interface_ip_mtu_size - sizeof(NX_IP_HEADER);
fragment_size = (fragment_size / NX_IP_ALIGN_FRAGS) * NX_IP_ALIGN_FRAGS;
/* Loop to break the source packet into fragments and send each out through
the associated driver. */
while (remaining_bytes)
{
/* Allocate a packet from the default packet pool. */
status = _nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &fragment_packet, NX_IP_PACKET, TX_NO_WAIT);
/* Determine if there is a packet available. */
if (status)
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the fragment failure count. */
ip_ptr -> nx_ip_fragment_failures++;
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
/* Increment the IP transmit resource error count. */
ip_ptr -> nx_ip_transmit_resource_errors++;
#endif
/* Error, not enough packets to perform the fragmentation... release the
source packet and return. */
_nx_packet_transmit_release(driver_req_ptr -> nx_ip_driver_packet);
return;
}
/* Set the proper interface. */
fragment_packet -> nx_packet_ip_interface = driver_req_ptr -> nx_ip_driver_packet -> nx_packet_ip_interface;
/* Calculate the size of this fragment. */
if (remaining_bytes > fragment_size)
{
copy_remaining_size = fragment_size;
remaining_bytes -= fragment_size;
}
else
{
copy_remaining_size = remaining_bytes;
remaining_bytes = 0;
}
/* Copy data. */
while (copy_remaining_size)
{
/* We need to copy the remaining bytes into the new packet and then move to the next
packet. */
if (copy_remaining_size > (ULONG)(source_packet -> nx_packet_append_ptr - source_ptr))
{
copy_size = (ULONG)(source_packet -> nx_packet_append_ptr - source_ptr);
}
else
{
copy_size = copy_remaining_size;
}
status = _nx_packet_data_append(fragment_packet, source_ptr, copy_size, ip_ptr -> nx_ip_default_packet_pool, NX_NO_WAIT);
/* Determine if there is a packet available. */
if (status)
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the fragment failure count. */
ip_ptr -> nx_ip_fragment_failures++;
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
/* Increment the IP transmit resource error count. */
ip_ptr -> nx_ip_transmit_resource_errors++;
#endif
/* Error, not enough packets to perform the fragmentation... release the
source packet and return. */
_nx_packet_transmit_release(driver_req_ptr -> nx_ip_driver_packet);
_nx_packet_release(fragment_packet);
return;
}
/* Reduce the remaining size. */
copy_remaining_size -= copy_size;
if (copy_size == (UINT)(source_packet -> nx_packet_append_ptr - source_ptr))
{
/* Move to the next physical packet in the source message. */
/* Determine if there is a next packet. */
if (source_packet -> nx_packet_next)
{
/* Move to the next physical packet in the source message. */
source_packet = source_packet -> nx_packet_next;
/* Setup new source pointer. */
source_ptr = source_packet -> nx_packet_prepend_ptr;
}
else if (remaining_bytes)
{
/* Error, no next packet but current packet is exhausted and there are
remaining bytes. */
#ifndef NX_DISABLE_IP_INFO
/* Increment the invalid transmit packet count. */
ip_ptr -> nx_ip_invalid_transmit_packets++;
/* Increment the fragment failures count. */
ip_ptr -> nx_ip_fragment_failures++;
#endif
/* Error, not enough packets to perform the fragmentation... release the
source packet and return. */
_nx_packet_transmit_release(driver_req_ptr -> nx_ip_driver_packet);
_nx_packet_release(fragment_packet);
return;
}
}
else
{
/* Copy finished. */
source_ptr += copy_size;
}
}
/* Setup the fragment packet pointers. */
fragment_packet -> nx_packet_prepend_ptr = fragment_packet -> nx_packet_prepend_ptr - sizeof(NX_IP_HEADER);
fragment_packet -> nx_packet_length += sizeof(NX_IP_HEADER);
/* Setup the fragment's IP header. */
fragment_header_ptr = (NX_IP_HEADER *)fragment_packet -> nx_packet_prepend_ptr;
/* Setup the new IP header. */
fragment_header_ptr -> nx_ip_header_word_0 = (source_header_ptr -> nx_ip_header_word_0 & ~NX_LOWER_16_MASK) | fragment_packet -> nx_packet_length;
fragment_header_ptr -> nx_ip_header_word_1 = source_header_ptr -> nx_ip_header_word_1 | (fragment_offset / 8);
fragment_header_ptr -> nx_ip_header_word_2 = source_header_ptr -> nx_ip_header_word_2 & ~NX_LOWER_16_MASK;
fragment_header_ptr -> nx_ip_header_source_ip = source_header_ptr -> nx_ip_header_source_ip;
fragment_header_ptr -> nx_ip_header_destination_ip = source_header_ptr -> nx_ip_header_destination_ip;
/* Determine if this is the last fragment. */
if (remaining_bytes)
{
/* Not the last fragment, so set the more fragments bit. */
fragment_header_ptr -> nx_ip_header_word_1 = fragment_header_ptr -> nx_ip_header_word_1 | NX_IP_MORE_FRAGMENT;
}
#ifndef NX_DISABLE_IP_TX_CHECKSUM
/* Build the IP checksum for this fragment. */
temp = fragment_header_ptr -> nx_ip_header_word_0;
checksum = (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK);
temp = fragment_header_ptr -> nx_ip_header_word_1;
checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK);
temp = fragment_header_ptr -> nx_ip_header_word_2;
checksum += (temp >> NX_SHIFT_BY_16);
temp = fragment_header_ptr -> nx_ip_header_source_ip;
checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK);
temp = fragment_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 fragment header. */
fragment_header_ptr -> nx_ip_header_word_2 = fragment_header_ptr -> nx_ip_header_word_2 | (NX_LOWER_16_MASK & (~checksum));
#endif /* NX_DISABLE_IP_TX_CHECKSUM */
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the IP header. */
NX_CHANGE_ULONG_ENDIAN(fragment_header_ptr -> nx_ip_header_word_0);
NX_CHANGE_ULONG_ENDIAN(fragment_header_ptr -> nx_ip_header_word_1);
NX_CHANGE_ULONG_ENDIAN(fragment_header_ptr -> nx_ip_header_word_2);
NX_CHANGE_ULONG_ENDIAN(fragment_header_ptr -> nx_ip_header_source_ip);
NX_CHANGE_ULONG_ENDIAN(fragment_header_ptr -> nx_ip_header_destination_ip);
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP fragments sent count. */
ip_ptr -> nx_ip_total_fragments_sent++;
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += fragment_packet -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif
/* Send the packet to the associated driver for output. */
driver_request.nx_ip_driver_packet = fragment_packet;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, fragment_packet, fragment_packet -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
(fragment_packet -> nx_packet_ip_interface -> nx_interface_link_driver_entry)(&driver_request);
/* Increase offset. */
fragment_offset += fragment_size;
}
#ifndef NX_DISABLE_IP_INFO
/* Increment the total number of successful fragment requests. */
ip_ptr -> nx_ip_successful_fragment_requests++;
#endif
/* The original packet has been sent out in fragments... release it! */
_nx_packet_transmit_release(driver_req_ptr -> nx_ip_driver_packet);
}

View File

@ -0,0 +1,136 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_fragment_timeout_check PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks for timeout conditions on the first fragment */
/* in the IP re-assembly list. If the head pointer is the same */
/* between execution of this routine the head fragment is deleted and */
/* its packets are released. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_packet_release Release packet */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_fragment_timeout_check(NX_IP *ip_ptr)
{
NX_PACKET *fragment;
NX_PACKET *next_fragment;
/* Determine if the head packet is still there. */
if ((ip_ptr -> nx_ip_timeout_fragment) &&
(ip_ptr -> nx_ip_timeout_fragment == ip_ptr -> nx_ip_fragment_assembly_head))
{
/* Save the head fragment pointer. */
fragment = ip_ptr -> nx_ip_fragment_assembly_head;
/* Yes, we need to remove this fragment from the assembly queue and release it. */
ip_ptr -> nx_ip_fragment_assembly_head = fragment -> nx_packet_queue_next;
/* Determine if we need to modify the fragment assembly tail pointer. */
if (ip_ptr -> nx_ip_fragment_assembly_tail == fragment)
{
/* If the tail pointer is the same, then the list is really empty now so
just set the tail pointer to NULL. */
ip_ptr -> nx_ip_fragment_assembly_tail = NX_NULL;
}
#ifndef NX_DISABLE_IP_INFO
/* Increment the re-assembly failures count. */
ip_ptr -> nx_ip_reassembly_failures++;
#endif
/* Walk the chain of fragments for this fragment re-assembly. */
do
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Pickup the next fragment. */
next_fragment = fragment -> nx_packet_fragment_next;
/* Release this fragment. */
_nx_packet_release(fragment);
/* Reassign the fragment pointer. */
fragment = next_fragment;
} while (fragment);
/* Set the timeout fragment head to NULL so the next fragment gets a full timeout. */
ip_ptr -> nx_ip_timeout_fragment = NX_NULL;
}
else
{
/* Assign the fragment head to the timeout pointer. */
ip_ptr -> nx_ip_timeout_fragment = ip_ptr -> nx_ip_fragment_assembly_head;
}
}

View File

@ -0,0 +1,161 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_gateway_address_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function finds the correct interface for the supplied ip */
/* address and applies that interface and the supplied gateway address */
/* as the IP task gateway for sending IP packets with addresses not in */
/* the local network. */
/* */
/* Note 1: if the gateway address is zero, the IP gateway address and */
/* gateway interface pointer are set to null. */
/* */
/* Note 2: For a gateway address is non zero, the IP gateway address */
/* and gateway interface pointer must be non null, or this function */
/* will return an error status. */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* ip_address Gateway IP address */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_gateway_address_set(NX_IP *ip_ptr, ULONG ip_address)
{
int i;
TX_INTERRUPT_SAVE_AREA
NX_INTERFACE *nx_ip_interface = NX_NULL;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_GATEWAY_ADDRESS_SET, ip_ptr, ip_address, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Obtain the IP internal mutex so the Gateway IP address can be setup. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Determine if the caller is trying to clear the IP gateway. */
if (ip_address == 0x0)
{
/* They are. Ok to clear gateway and gateway interface. */
/* Disable interrupts. */
TX_DISABLE
ip_ptr -> nx_ip_gateway_address = 0x0;
ip_ptr -> nx_ip_gateway_interface = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Unlock the mutex, and return success status. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
return(NX_SUCCESS);
}
/* Loop through all the interfaces to find the one for the input gateway address. */
for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
{
/* Must be a valid interface. Match the network subnet of the interface and input address. */
if ((ip_ptr -> nx_ip_interface[i].nx_interface_valid) &&
((ip_address & (ip_ptr -> nx_ip_interface[i].nx_interface_ip_network_mask)) ==
ip_ptr -> nx_ip_interface[i].nx_interface_ip_network))
{
/* This is the interface for the gateway. */
nx_ip_interface = &(ip_ptr -> nx_ip_interface[i]);
/* Break out of the search. */
break;
}
}
/* Check if we found an interface. */
if (nx_ip_interface == NX_NULL)
{
/* None found. Unlock the mutex, and return the error status. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
return(NX_IP_ADDRESS_ERROR);
}
/* Disable interrupts. */
TX_DISABLE
/* Setup the gateway address and interface for the IP task. */
ip_ptr -> nx_ip_gateway_address = ip_address;
ip_ptr -> nx_ip_gateway_interface = nx_ip_interface;
/* Restore interrupts. */
TX_RESTORE
/* Release the protection mutex. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return completion status. */
return(NX_SUCCESS);
}

190
common/src/nx_ip_info_get.c Normal file
View File

@ -0,0 +1,190 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves information about the specified IP */
/* instance. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* ip_total_packets_sent Destination for number of */
/* packets sent */
/* ip_total_bytes_sent Destination for number of */
/* bytes sent */
/* ip_total_packets_received Destination for number of */
/* packets received */
/* ip_total_bytes_received Destination for number of */
/* bytes received */
/* ip_invalid_packets Destination for number of */
/* invalid packets */
/* ip_receive_packets_dropped Destination for number of */
/* packets dropped */
/* ip_receive_checksum_errors Destination for number of */
/* checksum errors */
/* ip_send_packets_dropped Destination for number of */
/* send packets dropped */
/* ip_total_fragments_sent Destination for number of */
/* fragments sent */
/* ip_total_fragments_received Destination for number of */
/* fragments received */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_info_get(NX_IP *ip_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)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_INFO_GET, ip_ptr, ip_ptr -> nx_ip_total_bytes_sent, ip_ptr -> nx_ip_total_bytes_received, ip_ptr -> nx_ip_receive_packets_dropped, NX_TRACE_IP_EVENTS, 0, 0)
/* Obtain protection on this IP instance. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Determine if IP total packets sent is wanted. */
if (ip_total_packets_sent)
{
/* Return the number of IP total packets sent by this IP instance. */
*ip_total_packets_sent = ip_ptr -> nx_ip_total_packets_sent;
}
/* Determine if IP total bytes sent is wanted. */
if (ip_total_bytes_sent)
{
/* Return the number of IP total bytes sent by this IP instance. */
*ip_total_bytes_sent = ip_ptr -> nx_ip_total_bytes_sent;
}
/* Determine if IP total packets received is wanted. */
if (ip_total_packets_received)
{
/* Return the number of IP total packets received by this IP instance. */
*ip_total_packets_received = ip_ptr -> nx_ip_total_packets_received;
}
/* Determine if IP total bytes received is wanted. */
if (ip_total_bytes_received)
{
/* Return the number of IP total bytes received by this IP instance. */
*ip_total_bytes_received = ip_ptr -> nx_ip_total_bytes_received;
}
/* Determine if IP invalid packets is wanted. */
if (ip_invalid_packets)
{
/* Return the number of IP invalid packets received by this IP instance. */
*ip_invalid_packets = ip_ptr -> nx_ip_invalid_packets;
}
/* Determine if IP receive packets dropped is wanted. */
if (ip_receive_packets_dropped)
{
/* Return the number of IP receive packets dropped by this IP instance. */
*ip_receive_packets_dropped = ip_ptr -> nx_ip_receive_packets_dropped;
}
/* Determine if IP receive checksum errors is wanted. */
if (ip_receive_checksum_errors)
{
/* Return the number of IP receive checksum errors by this IP instance. */
*ip_receive_checksum_errors = ip_ptr -> nx_ip_receive_checksum_errors;
}
/* Determine if IP send packets dropped is wanted. */
if (ip_send_packets_dropped)
{
/* Return the number of IP send packets dropped by this IP instance. */
*ip_send_packets_dropped = ip_ptr -> nx_ip_send_packets_dropped;
}
/* Determine if IP total fragments sent is wanted. */
if (ip_total_fragments_sent)
{
/* Return the number of IP total fragments sent by this IP instance. */
*ip_total_fragments_sent = ip_ptr -> nx_ip_total_fragments_sent;
}
/* Determine if IP total fragments received is wanted. */
if (ip_total_fragments_received)
{
/* Return the number of IP total fragments received by this IP instance. */
*ip_total_fragments_received = ip_ptr -> nx_ip_total_fragments_received;
}
/* Release the protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return success to the caller. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Locate NetX IP data in this file. */
#define NX_IP_INIT
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the various control data structures for */
/* the Internet Protocol component. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _nx_system_initialize System initialization */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_initialize(VOID)
{
/* Initialize the created IP instance variables. */
_nx_ip_created_ptr = NX_NULL;
_nx_ip_created_count = 0;
}

View File

@ -0,0 +1,107 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_interface_address_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves the IP address and the network mask and */
/* returns them to the caller. */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* interface_index IP Interface Index */
/* ip_address Pointer to interface IP address */
/* network_mask Pointer to interface network mask */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_interface_address_get(NX_IP *ip_ptr, ULONG interface_index, ULONG *ip_address, ULONG *network_mask)
{
TX_INTERRUPT_SAVE_AREA
/* Check for valid interface ID */
if (interface_index >= NX_MAX_PHYSICAL_INTERFACES)
{
return(NX_INVALID_INTERFACE);
}
/* Check for interface being valid. */
if (!ip_ptr -> nx_ip_interface[interface_index].nx_interface_valid)
{
return(NX_INVALID_INTERFACE);
}
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_ADDRESS_GET, ip_ptr, ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_address,
ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_network_mask, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Disable interrupts. */
TX_DISABLE
/* Pickup the IP address and the network mask. */
*ip_address = ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_address;
*network_mask = ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_network_mask;
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_interface_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets the IP address and the network mask for the */
/* supplied IP instance. */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* interface_index IP Interface Index */
/* ip_address IP address */
/* network_mask Network mask */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_interface_address_set(NX_IP *ip_ptr, ULONG interface_index, ULONG ip_address, ULONG network_mask)
{
TX_INTERRUPT_SAVE_AREA
VOID (*address_change_notify)(NX_IP *, VOID *);
VOID *additional_info;
ULONG previous_ip_address;
ULONG previous_network_mask;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_ADDRESS_SET, ip_ptr, ip_address, network_mask, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Check for valid interface ID */
if (interface_index >= NX_MAX_PHYSICAL_INTERFACES)
{
return(NX_INVALID_INTERFACE);
}
/* Check for interface being valid. */
if (!ip_ptr -> nx_ip_interface[interface_index].nx_interface_valid)
{
return(NX_INVALID_INTERFACE);
}
/* Disable interrupts. */
TX_DISABLE
/* Save previous IP address and network mask. */
previous_ip_address = ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_address;
previous_network_mask = ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_network_mask;
/* Pickup the current notification callback and additional information pointers. */
address_change_notify = ip_ptr -> nx_ip_address_change_notify;
additional_info = ip_ptr -> nx_ip_address_change_notify_additional_info;
/* Setup the IP address and the network mask. */
ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_address = ip_address;
ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_network_mask = network_mask;
ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_network = ip_address & network_mask;
/* Ensure the RARP function is disabled. */
ip_ptr -> nx_ip_rarp_periodic_update = NX_NULL;
ip_ptr -> nx_ip_rarp_queue_process = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Determine if the application should be notified of the IP address and/or
network mask change. */
if ((address_change_notify) &&
((ip_address != previous_ip_address) || (network_mask != previous_network_mask)))
{
/* Yes, call the application's IP address change notify function. */
(address_change_notify)(ip_ptr, additional_info);
}
/* Initialize the ARP defend timeout. */
ip_ptr -> nx_ip_interface[interface_index].nx_interface_arp_defend_timeout = 0;
/* Return completion status. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,176 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_interface_attach PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function attaches a physical network interface to the IP */
/* instance, initializes and enables the driver. */
/* */
/* Note that the priority of this function is determined by the IP */
/* create service. */
/* */
/* INPUT */
/* */
/* ip_ptr_value Pointer to IP control block */
/* interface_name Name of this interface */
/* ip_address IP Address, in host byte order*/
/* network_mask Network Mask, in host byte */
/* order */
/* ip_link_driver User supplied link driver */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* tx_mutex_get Obtain protection mutex */
/* tx_mutex_put Release protection mutex */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_interface_attach(NX_IP *ip_ptr, CHAR *interface_name, ULONG ip_address, ULONG network_mask, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *))
{
int i;
NX_INTERFACE *nx_interface = NX_NULL;
NX_IP_DRIVER driver_request;
/* This function must be called within the system initialization
after nx_ip_create, before nx ip thread runs. */
for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
{
nx_interface = &(ip_ptr -> nx_ip_interface[i]);
if (!(nx_interface -> nx_interface_valid))
{
/* Find a valid entry. */
break;
}
}
if ((nx_interface == NX_NULL) || (i == NX_MAX_PHYSICAL_INTERFACES))
{
/* No more free entry. return. */
return(NX_NO_MORE_ENTRIES);
}
/* Obtain the IP internal mutex before calling the driver. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Mark the entry as valid. */
nx_interface -> nx_interface_valid = NX_TRUE;
/* Fill in the interface information. */
nx_interface -> nx_interface_ip_address = ip_address;
nx_interface -> nx_interface_ip_network_mask = network_mask;
nx_interface -> nx_interface_ip_network = ip_address & network_mask;
nx_interface -> nx_interface_link_driver_entry = ip_link_driver;
nx_interface -> nx_interface_ip_instance = ip_ptr;
nx_interface -> nx_interface_name = interface_name;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_INTERFACE_ATTACH, ip_ptr, ip_address, i, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* If the IP thread is already running, this service needs to go through the rest of the initializeation process. */
if (ip_ptr -> nx_ip_initialize_done == NX_TRUE)
{
/* First attach the interface to the device. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_INTERFACE_ATTACH;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[i]);
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
/* Call the link driver to initialize the hardware. Among other
responsibilities, the driver is required to provide the
Maximum Transfer Unit (MTU) for the physical layer. The MTU
should represent the actual physical layer transfer size
less the physical layer headers and trailers. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_INITIALIZE;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_INITIALIZE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/*
When an IP instance is created, the first interface (nx_ip_interface[0]) is configured using parameters
provided in the IP create call.
When IP thread runs, it invokes the 1st interface link driver for link initialization.
*/
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry) (&driver_request);
/* Call the link driver again to enable the interface. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_ENABLE;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_LINK_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry) (&driver_request);
}
/* Release the IP internal mutex. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* All done. Return. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,133 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_interface_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves information related to a specified */
/* interface */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* interface_index Interface ID to query. */
/* interface_name Name of the interface */
/* ip_address Pointer to Interface IP address */
/* in host byte order */
/* network_mask Pointer to network mask */
/* destination, in host byte order */
/* mtu_size Pointer to storage space for MTU */
/* physical_address_msw Pointer to storage space for */
/* device phsyical address, MSW */
/* physical_address_lsw Pointer to storage space for */
/* device phsyical address, LSW */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_interface_info_get(NX_IP *ip_ptr, UINT interface_index, CHAR **interface_name,
ULONG *ip_address, ULONG *network_mask, ULONG *mtu_size,
ULONG *physical_address_msw, ULONG *physical_address_lsw)
{
NX_INTERFACE *nx_interface;
nx_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
if (!nx_interface -> nx_interface_valid)
{
return(NX_INVALID_INTERFACE);
}
if (interface_name)
{
*interface_name = nx_interface -> nx_interface_name;
}
if (ip_address)
{
*ip_address = nx_interface -> nx_interface_ip_address;
}
if (network_mask)
{
*network_mask = nx_interface -> nx_interface_ip_network_mask;
}
if (mtu_size)
{
*mtu_size = nx_interface -> nx_interface_ip_mtu_size;
}
if (physical_address_msw)
{
*physical_address_msw = nx_interface -> nx_interface_physical_address_msw;
}
if (physical_address_lsw)
{
*physical_address_lsw = nx_interface -> nx_interface_physical_address_lsw;
}
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_INTERFACE_INFO_GET, ip_ptr, nx_interface -> nx_interface_ip_address,
nx_interface -> nx_interface_physical_address_msw, nx_interface -> nx_interface_physical_address_lsw,
NX_TRACE_IP_EVENTS, 0, 0)
return(NX_SUCCESS);
}

View File

@ -0,0 +1,320 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_interface_status_check PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function polls the specified interface for the link state using*/
/* thread sleep for the necessary conditions n the IP instance. Where */
/* the requested status exists only at the IP instance, for example */
/* NX_IP_INITIALIZE_DONE this service supplies the IP setting for that */
/* status. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* interface_indes Index into IP interface list */
/* needed_status Status needed request */
/* actual_status Pointer to return status area */
/* wait_option Maximum suspension time */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* (ip_link_driver) User supplied link driver */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* tx_thread_sleep Sleep until events are */
/* satisfied */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_interface_status_check(NX_IP *ip_ptr, UINT interface_index, ULONG needed_status,
ULONG *actual_status, ULONG wait_option)
{
ULONG current_status;
NX_IP_DRIVER driver_request;
ULONG return_value;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *trace_event;
ULONG trace_timestamp;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_STATUS_CHECK, ip_ptr, needed_status, 0, wait_option, NX_TRACE_IP_EVENTS, &trace_event, &trace_timestamp)
/* Loop to keep checking for the proper status bits. */
do
{
/* Clear the current status. */
current_status = 0;
/* Process according to the status option specified. */
if (needed_status & NX_IP_INITIALIZE_DONE)
{
/* Check for initialization complete. */
if (ip_ptr -> nx_ip_initialize_done)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_INITIALIZE_DONE;
}
}
if (needed_status & NX_IP_ADDRESS_RESOLVED)
{
/* Check for a non-zero IP address. */
if (ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_address)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_ADDRESS_RESOLVED;
}
}
if (needed_status & NX_IP_LINK_ENABLED)
{
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Build the driver request structure. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_GET_STATUS;
driver_request.nx_ip_driver_return_ptr = &return_value;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_GET_STATUS, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Call link level driver. */
(ip_ptr -> nx_ip_interface[interface_index].nx_interface_link_driver_entry) (&driver_request);
/* Check for a link up condition. */
if (ip_ptr -> nx_ip_interface[interface_index].nx_interface_link_up)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_LINK_ENABLED;
}
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
}
if (needed_status & NX_IP_ARP_ENABLED)
{
/* Check for ARP being enabled. */
if (ip_ptr -> nx_ip_arp_periodic_update)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_ARP_ENABLED;
}
}
if (needed_status & NX_IP_UDP_ENABLED)
{
/* Check for UDP being enabled. */
if (ip_ptr -> nx_ip_udp_packet_receive)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_UDP_ENABLED;
}
}
if (needed_status & NX_IP_TCP_ENABLED)
{
/* Check for TCP being enabled. */
if (ip_ptr -> nx_ip_tcp_packet_receive)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_TCP_ENABLED;
}
}
if (needed_status & NX_IP_IGMP_ENABLED)
{
/* Check for IGMP being enabled. */
if (ip_ptr -> nx_ip_igmp_packet_receive)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_IGMP_ENABLED;
}
}
if (needed_status & NX_IP_RARP_COMPLETE)
{
/* This is effectively the same as the IP address resolved... */
/* Check for a non-zero IP address. */
if (ip_ptr -> nx_ip_interface[interface_index].nx_interface_ip_address)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_RARP_COMPLETE;
}
}
if (needed_status & NX_IP_INTERFACE_LINK_ENABLED)
{
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Build the driver request structure. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_GET_STATUS;
driver_request.nx_ip_driver_return_ptr = &return_value;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_GET_STATUS, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Call link level driver. */
(ip_ptr -> nx_ip_interface[interface_index].nx_interface_link_driver_entry) (&driver_request);
/* If the driver does not recognize this keyword, we fall back to reading the IP link status.*/
if (driver_request.nx_ip_driver_status != NX_SUCCESS)
{
if (driver_request.nx_ip_driver_status == NX_UNHANDLED_COMMAND)
{
if (ip_ptr -> nx_ip_interface[interface_index].nx_interface_link_up)
{
current_status = current_status | NX_IP_INTERFACE_LINK_ENABLED;
}
}
}
else
{
/* Check for a link up condition. */
if (return_value == NX_TRUE)
{
/* Yes, set the appropriate bit in the current status. */
current_status = current_status | NX_IP_INTERFACE_LINK_ENABLED;
}
}
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
}
/* Determine if current status is the same. If so, break out
of this polling loop. */
if (current_status == needed_status)
{
break;
}
/* Check for suspension request. */
if (wait_option)
{
/* Decrease the wait time and sleep. */
wait_option--;
/* Sleep for a tick and check again. */
tx_thread_sleep(NX_IP_STATUS_CHECK_WAIT_TIME);
}
else
{
/* Get out of the loop. */
break;
}
/* Check for a valid ip structure. */
if (ip_ptr -> nx_ip_id != NX_IP_ID)
{
/* Clear the return status bits. */
*actual_status = 0;
/* Return an error indicating the IP pointer is no longer valid. */
return(NX_PTR_ERROR);
}
} while (NX_FOREVER);
/* Place the current status in the return destination. */
*actual_status = current_status;
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_IP_STATUS_CHECK, 0, 0, current_status, 0)
/* Determine what status to return. */
if (needed_status == current_status)
{
/* Return a success. */
return(NX_SUCCESS);
}
else
{
/* Return an error. */
return(NX_NOT_SUCCESSFUL);
}
}

View File

@ -0,0 +1,90 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_link_status_change_notify_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function configures the link status change notify callback */
/* function specified by the application. */
/* */
/* If a NULL pointer is supplied, the link status change notify */
/* callback feature is disabled. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP instance */
/* link_status_change_notify Routine to call when link */
/* staus is changed */
/* */
/* OUTPUT */
/* */
/* status Actual completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_link_status_change_notify_set(NX_IP *ip_ptr, VOID (*link_status_change_notify)(NX_IP *ip_ptr, UINT interface_index, UINT link_up))
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Setup the link status change callback function pointer. */
ip_ptr -> nx_ip_link_status_change_callback = link_status_change_notify;
/* Restore interrupts. */
TX_RESTORE
/* Return successful completion. */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,120 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_loopback_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function prepends an IP header and sends an IP packet to the */
/* appropriate link driver. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* packet_release Whether or not to release */
/* the original packet */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_ip_packet_deferred_receive Receive loopback packet */
/* _nx_packet_copy Copy packet for loopback */
/* _nx_packet_transmit_release Release transmit packet */
/* */
/* CALLED BY */
/* */
/* NetX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_loopback_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT packet_release)
{
NX_PACKET *packet_copy;
/* Copy the packet so it can be enqueued properly by the receive
processing. */
if (_nx_packet_copy(packet_ptr, &packet_copy, ip_ptr -> nx_ip_default_packet_pool, NX_NO_WAIT) == NX_SUCCESS)
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif
/* Send the packet to this IP's receive processing queue like it came in from the
driver. */
_nx_ip_packet_deferred_receive(ip_ptr, packet_copy);
}
#ifndef NX_DISABLE_IP_INFO
else
{
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
/* Increment the IP transmit resource error count. */
ip_ptr -> nx_ip_transmit_resource_errors++;
}
#endif
if (packet_release)
{
/* Release the transmit packet. */
_nx_packet_transmit_release(packet_ptr);
}
return;
}

View File

@ -0,0 +1,111 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_packet_deferred_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function receives a packet from the link driver (usually the */
/* link driver's input ISR) and places it in the deferred receive */
/* packet queue. This moves the minimal receive packet processing */
/* from the ISR to the IP helper thread. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* tx_event_flags_set Set events for IP thread */
/* */
/* CALLED BY */
/* */
/* Application I/O Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Check to see if the deferred processing queue is empty. */
if (ip_ptr -> nx_ip_deferred_received_packet_head)
{
/* Not empty, just place the packet at the end of the queue. */
(ip_ptr -> nx_ip_deferred_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
packet_ptr -> nx_packet_queue_next = NX_NULL;
ip_ptr -> nx_ip_deferred_received_packet_tail = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Empty deferred receive processing queue. Just setup the head pointers and
set the event flags to ensure the IP helper thread looks at the deferred processing
queue. */
ip_ptr -> nx_ip_deferred_received_packet_head = packet_ptr;
ip_ptr -> nx_ip_deferred_received_packet_tail = packet_ptr;
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Restore interrupts. */
TX_RESTORE
/* Wakeup IP helper thread to process the IP deferred receive. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_RECEIVE_EVENT, TX_OR);
}
}

View File

@ -0,0 +1,785 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_igmp.h"
#include "nx_packet.h"
#include "nx_udp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_packet_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function receives a packet from the link driver (usually the */
/* link driver's input ISR) and either processes it or places it in a */
/* deferred processing queue, depending on the complexity of the */
/* packet. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* (ip_tcp_packet_receive) Receive a TCP packet */
/* (ip_udp_packet_receive) Receive a UDP packet */
/* (ip_icmp_packet_receive) Receive a ICMP packet */
/* (ip_igmp_packet_receive) Receive a IGMP packet */
/* (ip_raw_ip_raw_packet_processing) Process a Raw IP packet */
/* (nx_ip_forward_packet_process) Forward IP packet */
/* _nx_igmp_multicast_check Check for Multicast match */
/* _nx_packet_release Packet release function */
/* tx_event_flags_set Set events for IP thread */
/* */
/* CALLED BY */
/* */
/* Application I/O Driver */
/* _nx_ip_packet_send IP loopback packet send */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_PACKET *before_last_packet;
NX_PACKET *last_packet;
NX_IP_HEADER *ip_header_ptr;
ULONG *word_ptr;
ULONG ip_header_length;
ULONG protocol;
ULONG delta;
UCHAR drop_packet = 0;
NX_UDP_HEADER *udp_header_ptr;
UINT dest_port;
#ifndef NX_DISABLE_IP_RX_CHECKSUM
ULONG ip_option_words;
ULONG checksum;
ULONG temp;
#endif /* NX_DISABLE_IP_RX_CHECKSUM */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet count. */
ip_ptr -> nx_ip_total_packets_received++;
#endif
/* If packet_ptr -> nx_packet_ip_interface is not set, stamp the packet with interface[0].
Legacy Ethernet drivers do not stamp incoming packets. */
if (packet_ptr -> nx_packet_ip_interface == NX_NULL)
{
packet_ptr -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[0]);
}
/* It's assumed that the IP link driver has positioned the top pointer in the
packet to the start of the IP address... so that's where we will start. */
ip_header_ptr = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
#ifdef NX_ENABLE_IP_PACKET_FILTER
/* Check if the IP packet filter is set. */
if (ip_ptr -> nx_ip_packet_filter)
{
/* Yes, call the IP packet filter routine. */
if ((ip_ptr -> nx_ip_packet_filter((VOID *)(ip_header_ptr), NX_IP_PACKET_IN)) != NX_SUCCESS)
{
/* Drop the packet. */
_nx_packet_release(packet_ptr);
return;
}
}
#endif /* NX_ENABLE_IP_PACKET_FILTER */
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the IP header. */
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);
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IP_RECEIVE, ip_ptr, ip_header_ptr -> nx_ip_header_source_ip, packet_ptr, packet_ptr -> nx_packet_length, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Make sure the IP length matches the packet length. Some Ethernet devices
add padding to small packets, which results in a discrepancy between the
packet length and the IP header length. */
if (packet_ptr -> nx_packet_length != (ip_header_ptr -> nx_ip_header_word_0 & NX_LOWER_16_MASK))
{
/* Determine if the packet length is less than the size reported in the IP header. */
if (packet_ptr -> nx_packet_length < (ip_header_ptr -> nx_ip_header_word_0 & NX_LOWER_16_MASK))
{
/* Packet is too small! */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP invalid packet error. */
ip_ptr -> nx_ip_invalid_packets++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Invalid packet length, just release it. */
_nx_packet_release(packet_ptr);
/* The function is complete, just return! */
return;
}
/* Calculate the difference in the length. */
delta = packet_ptr -> nx_packet_length - (ip_header_ptr -> nx_ip_header_word_0 & NX_LOWER_16_MASK);
/* Adjust the packet length. */
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - delta;
/* Adjust the append pointer. */
/* Loop to process adjustment that spans multiple packets. */
while (delta)
{
/* Determine if the packet is chained (or still chained after the adjustment). */
if (packet_ptr -> nx_packet_last == NX_NULL)
{
/* No, packet is not chained, simply adjust the append pointer in the packet. */
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_append_ptr - delta;
/* Break out of the loop, since the adjustment is complete. */
break;
}
/* Pickup the pointer to the last packet. */
last_packet = packet_ptr -> nx_packet_last;
/* Determine if the amount to adjust is less than the payload in the last packet. */
if (((ULONG)(last_packet -> nx_packet_append_ptr - last_packet -> nx_packet_prepend_ptr)) > delta)
{
/* Yes, simply adjust the append pointer of the last packet in the chain. */
last_packet -> nx_packet_append_ptr = last_packet -> nx_packet_append_ptr - delta;
/* Get out of the loop, since the adjustment is complete. */
break;
}
else
{
/* Adjust the delta by the amount in the last packet. */
delta = delta - ((ULONG)(last_packet -> nx_packet_append_ptr - last_packet -> nx_packet_prepend_ptr));
/* Find the packet before the last packet. */
before_last_packet = packet_ptr;
while (before_last_packet -> nx_packet_next != last_packet)
{
/* Move to the next packet in the chain. */
before_last_packet = before_last_packet -> nx_packet_next;
}
/* At this point, we need to release the last packet and adjust the other packet
pointers. */
/* Ensure the next packet pointer is NULL in what is now the last packet. */
before_last_packet -> nx_packet_next = NX_NULL;
/* Determine if the packet is still chained. */
if (packet_ptr != before_last_packet)
{
/* Yes, the packet is still chained, setup the last packet pointer. */
packet_ptr -> nx_packet_last = before_last_packet;
}
else
{
/* The packet is no longer chained, set the last packet pointer to NULL. */
packet_ptr -> nx_packet_last = NX_NULL;
}
/* Release the last packet. */
_nx_packet_release(last_packet);
}
}
}
/* Get IP header length. */
ip_header_length = (ip_header_ptr -> nx_ip_header_word_0 & NX_IP_LENGTH_MASK) >> 24;
/* Check for minimal packet length. The check is done after the endian swapping
since the compiler may possibly be able to optimize the lookup of
"nx_packet_length" and therefore reduce the amount of work performing these
size checks. The endian logic is okay since packets must always have
payloads greater than the IP header in size. */
if ((packet_ptr -> nx_packet_length <= (ip_header_length << 2)) ||
(ip_header_length < NX_IP_NORMAL_LENGTH))
{
/* Packet is too small! */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP invalid packet error. */
ip_ptr -> nx_ip_invalid_packets++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Invalid packet length, just release it. */
_nx_packet_release(packet_ptr);
/* The function is complete, just return! */
return;
}
#ifndef NX_DISABLE_RX_SIZE_CHECKING
#endif /* NX_DISABLE_RX_SIZE_CHECKING */
#ifndef NX_DISABLE_IP_RX_CHECKSUM
/* Perform a checksum on the packet header. */
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 & NX_LOWER_16_MASK);
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);
/* Take the one's complement. */
checksum = NX_LOWER_16_MASK & ~checksum;
/* Determine if the checksum is valid. */
if (checksum)
{
/* Check for IP options before we give up on the packet. */
/* Setup a pointer to the first option word. */
word_ptr = ((ULONG *)((VOID *)ip_header_ptr)) + NX_IP_NORMAL_LENGTH;
/* Determine if there are options in the IP header that make the length greater
than the default length. */
if (ip_header_length > NX_IP_NORMAL_LENGTH)
{
/* IP header with options is present. */
/* Un-complement the checksum. */
checksum = ~checksum & NX_LOWER_16_MASK;
/* Calculate the number of option words. */
ip_option_words = ip_header_length - NX_IP_NORMAL_LENGTH;
/* Loop to adjust the checksum. */
do
{
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, this macro
will swap the endian of the IP header option word. */
NX_CHANGE_ULONG_ENDIAN(*word_ptr);
/* Add this word to the checksum. */
temp = *word_ptr;
checksum += (temp >> NX_SHIFT_BY_16);
checksum += (NX_LOWER_16_MASK & temp);
/* Move the option word pointer and decrement the number of option words. */
word_ptr++;
ip_option_words--;
} while (ip_option_words);
/* 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);
/* Perform the one's complement on the checksum again. */
checksum = NX_LOWER_16_MASK & ~checksum;
}
/* Check the checksum again. */
if (checksum)
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP invalid packet error. */
ip_ptr -> nx_ip_invalid_packets++;
/* Increment the IP checksum error. */
ip_ptr -> nx_ip_receive_checksum_errors++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Checksum error, just release it. */
_nx_packet_release(packet_ptr);
/* The function is complete, just return! */
return;
}
else
{
/* If the packet checksum is okay, make sure the source and destination IP
addresses are placed immediately before the next protocol layer. */
/* Build a pointer to what will be the last word of the IP header after we
remove the IP options. Basically, all we have to do is move it backwards
since it was setup previously. */
word_ptr--;
/* Move the destination IP. */
*word_ptr-- = ip_header_ptr -> nx_ip_header_destination_ip;
*word_ptr-- = ip_header_ptr -> nx_ip_header_source_ip;
*word_ptr-- = ip_header_ptr -> nx_ip_header_word_2;
*word_ptr-- = ip_header_ptr -> nx_ip_header_word_1;
*word_ptr = (ip_header_ptr -> nx_ip_header_word_0 & ~NX_IP_LENGTH_MASK) |
NX_IP_VERSION;
/* Update the ip_header_ptr and the packet and the packet prepend pointer
and length. */
ip_header_ptr = (NX_IP_HEADER *)((VOID *)word_ptr);
packet_ptr -> nx_packet_prepend_ptr = (UCHAR *)word_ptr;
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length -
((ip_header_length - NX_IP_NORMAL_LENGTH) * sizeof(ULONG));
}
}
#else
/* IP receive checksum processing is disabled... just check for and remove if
necessary the IP option words. */
/* Check for IP options before we process the packet. */
/* Determine if there are options in the IP header that make the length greater
than the default length. */
if (ip_header_length > NX_IP_NORMAL_LENGTH)
{
/* Setup a pointer to the last option word. */
word_ptr = ((ULONG *)ip_header_ptr) + ip_header_length - 1;
/* Remove the option words prior to handling the IP header. */
*word_ptr-- = ip_header_ptr -> nx_ip_header_destination_ip;
*word_ptr-- = ip_header_ptr -> nx_ip_header_source_ip;
*word_ptr-- = ip_header_ptr -> nx_ip_header_word_2;
*word_ptr-- = ip_header_ptr -> nx_ip_header_word_1;
*word_ptr = (ip_header_ptr -> nx_ip_header_word_0 & ~NX_IP_LENGTH_MASK) |
NX_IP_VERSION;
/* Update the ip_header_ptr and the packet and the packet prepend pointer
and length. */
ip_header_ptr = (NX_IP_HEADER *)word_ptr;
packet_ptr -> nx_packet_prepend_ptr = (UCHAR *)word_ptr;
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length -
((ip_header_length - NX_IP_NORMAL_LENGTH) * sizeof(ULONG));
}
#endif
#ifdef NX_ENABLE_SOURCE_ADDRESS_CHECK
/* Check whether source address is valid. */
/* Section 3.2.1.3, page 30, RFC 1122. */
if (packet_ptr -> nx_packet_ip_interface -> nx_interface_address_mapping_needed == NX_TRUE)
{
if (((ip_header_ptr -> nx_ip_header_source_ip & ~(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask)) == ~(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask)) ||
(((ip_header_ptr -> nx_ip_header_source_ip & ~(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask)) == 0) &&
(ip_header_ptr -> nx_ip_header_source_ip != 0)) ||
((ip_header_ptr -> nx_ip_header_source_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE))
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP invalid address error. */
ip_ptr -> nx_ip_invalid_receive_address++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Toss the IP packet since we don't know what to do with it! */
_nx_packet_release(packet_ptr);
/* Return to caller. */
return;
}
}
#endif /* NX_ENABLE_SOURCE_ADDRESS_CHECK */
/* Determine if the IP datagram is for this IP address or a broadcast IP on this
network. */
if ((ip_header_ptr -> nx_ip_header_destination_ip == packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address) ||
/* Check for incoming IP address of zero. Incoming IP address of zero should
be received regardless of our current IP address. */
(ip_header_ptr -> nx_ip_header_destination_ip == 0) ||
/* Check for IP broadcast. */
(((ip_header_ptr -> nx_ip_header_destination_ip & packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask) ==
packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network) &&
((ip_header_ptr -> nx_ip_header_destination_ip & ~(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask)) ==
~(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask))) ||
/* Check for limited broadcast. */
(ip_header_ptr -> nx_ip_header_destination_ip == NX_IP_LIMITED_BROADCAST) ||
/* Check for loopback address. */
((ip_header_ptr -> nx_ip_header_destination_ip >= NX_IP_LOOPBACK_FIRST) &&
(ip_header_ptr -> nx_ip_header_destination_ip <= NX_IP_LOOPBACK_LAST)) ||
/* Check for valid Multicast address. */
(_nx_igmp_multicast_check(ip_ptr, ip_header_ptr -> nx_ip_header_destination_ip, packet_ptr -> nx_packet_ip_interface)))
{
/* Determine if this packet is fragmented. If so, place it on the deferred processing
queue. The input packet will then be processed by an IP system thread. */
if (ip_header_ptr -> nx_ip_header_word_1 & NX_IP_FRAGMENT_MASK)
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP receive fragments count. */
ip_ptr -> nx_ip_total_fragments_received++;
#endif
/* Yes, the incoming IP header is fragmented. Check to see if IP fragmenting
has been enabled. */
if (ip_ptr -> nx_ip_fragment_assembly)
{
/* Yes, fragmenting is available. Place the packet on the incoming
fragment queue. */
/* Disable interrupts. */
TX_DISABLE
/* Determine if the queue is empty. */
if (ip_ptr -> nx_ip_received_fragment_head)
{
/* Raw receive queue is not empty, add this packet to the end of
the queue. */
(ip_ptr -> nx_ip_received_fragment_tail) -> nx_packet_queue_next = packet_ptr;
packet_ptr -> nx_packet_queue_next = NX_NULL;
ip_ptr -> nx_ip_received_fragment_tail = packet_ptr;
}
else
{
/* Raw receive queue is empty. Just setup the head and tail pointers
to point to this packet. */
ip_ptr -> nx_ip_received_fragment_head = packet_ptr;
ip_ptr -> nx_ip_received_fragment_tail = packet_ptr;
packet_ptr -> nx_packet_queue_next = NX_NULL;
}
/* Restore interrupts. */
TX_RESTORE
/* Wakeup IP helper thread to process the IP fragment re-assembly. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_UNFRAG_EVENT, TX_OR);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Fragmentation has not been enabled, toss the packet! */
_nx_packet_release(packet_ptr);
}
/* In all cases, receive processing is finished. Return to caller. */
return;
}
/* Determine what protocol the current IP datagram is. */
protocol = ip_header_ptr -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK;
/* Remove the IP header from the packet. */
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER);
/* Adjust the length. */
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#ifndef NX_DISABLE_IP_INFO
/* Increment the number of packets delivered. */
ip_ptr -> nx_ip_total_packets_delivered++;
/* Increment the IP packet bytes received (not including the header). */
ip_ptr -> nx_ip_total_bytes_received += packet_ptr -> nx_packet_length;
#endif
/* Dispatch the protocol... Have we found a UDP packet? */
if (protocol == NX_IP_UDP)
{
if (ip_ptr -> nx_ip_udp_packet_receive)
{
/* Yes, dispatch it to the appropriate UDP handler if present. */
(ip_ptr -> nx_ip_udp_packet_receive)(ip_ptr, packet_ptr);
return;
}
/* UDP is not enabled. */
drop_packet = 1;
}
/* Is a TCP packet present? */
else if (protocol == NX_IP_TCP)
{
if (ip_ptr -> nx_ip_tcp_packet_receive)
{
/* Yes, dispatch it to the appropriate TCP handler if present. */
(ip_ptr -> nx_ip_tcp_packet_receive)(ip_ptr, packet_ptr);
return;
}
/* TCP is not enabled. */
drop_packet = 1;
}
/* Is a ICMP packet present? */
else if (protocol == NX_IP_ICMP)
{
if (ip_ptr -> nx_ip_icmp_packet_receive)
{
/* Yes, dispatch it to the appropriate ICMP handler if present. */
(ip_ptr -> nx_ip_icmp_packet_receive)(ip_ptr, packet_ptr);
return;
}
/* ICMP is not enabled. */
drop_packet = 1;
}
else if (protocol == NX_IP_IGMP)
{
if (ip_ptr -> nx_ip_igmp_packet_receive)
{
/* Yes, dispatch it to the appropriate IGMP handler if present. */
(ip_ptr -> nx_ip_igmp_packet_receive)(ip_ptr, packet_ptr);
return;
}
/* IGMP is not enabled. */
drop_packet = 1;
}
/* No protocol found so far. Determine if RAW IP is supported. */
if (ip_ptr -> nx_ip_raw_ip_processing && (drop_packet == 0))
{
/* Yes it is. Call the raw IP packet processing routine. */
(ip_ptr -> nx_ip_raw_ip_processing)(ip_ptr, packet_ptr);
/* Done, return to caller. */
return;
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Decrement the number of packets delivered. */
ip_ptr -> nx_ip_total_packets_delivered--;
/* Decrement the IP packet bytes received (not including the header). */
ip_ptr -> nx_ip_total_bytes_received -= packet_ptr -> nx_packet_length;
/* Increment the IP unknown protocol count. */
ip_ptr -> nx_ip_unknown_protocols_received++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Toss the IP packet since we don't know what to do with it! */
_nx_packet_release(packet_ptr);
/* Return to caller. */
return;
}
}
/* Does this IP interface define another forward packet handler other
than the NAT packet handler? */
else if (ip_ptr -> nx_ip_forward_packet_process)
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packets forwarded counter. */
ip_ptr -> nx_ip_packets_forwarded++;
#endif
/* The packet is not for this IP instance so call the
forward IP packet processing routine. */
(ip_ptr -> nx_ip_forward_packet_process)(ip_ptr, packet_ptr);
}
/* Try to receive the DHCP message before release this packet.
NetX should recieve the unicast DHCP message when interface IP address is zero. */
/* Check if this IP interface has IP address. */
else if (packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address == 0)
{
/* Determine what protocol the current IP datagram is. */
protocol = ip_header_ptr -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK;
/* Check if this packet is UDP message. */
if (protocol == NX_IP_UDP)
{
/* Remove the IP header from the packet. */
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER);
/* Adjust the length. */
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#ifndef NX_DISABLE_IP_INFO
/* Increment the number of packets delivered. */
ip_ptr -> nx_ip_total_packets_delivered++;
/* Increment the IP packet bytes received (not including the header). */
ip_ptr -> nx_ip_total_bytes_received += packet_ptr -> nx_packet_length;
#endif
/* Pickup the pointer to the head of the UDP packet. */
udp_header_ptr = (NX_UDP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the UDP header. */
NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0);
/* Pickup the destination UDP port. */
dest_port = (UINT)(udp_header_ptr -> nx_udp_header_word_0 & NX_LOWER_16_MASK);
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the UDP header. */
NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0);
/* Check if this packet is DHCP message. */
if (dest_port == 68)
{
if (ip_ptr -> nx_ip_udp_packet_receive)
{
/* Yes, dispatch it to the appropriate UDP handler if present. */
(ip_ptr -> nx_ip_udp_packet_receive)(ip_ptr, packet_ptr);
return;
}
}
}
#ifndef NX_DISABLE_IP_INFO
/* Decrement the number of packets delivered. */
ip_ptr -> nx_ip_total_packets_delivered--;
/* Decrement the IP packet bytes received (not including the header). */
ip_ptr -> nx_ip_total_bytes_received -= packet_ptr -> nx_packet_length;
/* Increment the IP invalid address error. */
ip_ptr -> nx_ip_invalid_receive_address++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Toss the IP packet since we don't know what to do with it! */
_nx_packet_release(packet_ptr);
/* Return to caller. */
return;
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP invalid address error. */
ip_ptr -> nx_ip_invalid_receive_address++;
/* Increment the IP receive packets dropped count. */
ip_ptr -> nx_ip_receive_packets_dropped++;
#endif
/* Toss the IP packet since we don't know what to do with it! */
_nx_packet_release(packet_ptr);
/* Return to caller. */
return;
}
}

View File

@ -0,0 +1,876 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
#include "nx_igmp.h"
#include "nx_arp.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_packet_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function prepends an IP header and sends an IP packet to the */
/* appropriate link driver. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* destination_ip Destination IP address */
/* type_of_service Type of service for packet */
/* time_to_live Time to live value for packet */
/* protocol Protocol being encapsulated */
/* fragment Don't fragment bit */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _nx_packet_copy Copy packet for loopback */
/* _nx_packet_transmit_release Release transmit packet */
/* _nx_ip_loopback_send Send packet via the LB driver */
/* (nx_ip_fragment_processing) Fragment processing */
/* (ip_link_driver) User supplied link driver */
/* */
/* CALLED BY */
/* */
/* NetX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
ULONG destination_ip, ULONG type_of_service, ULONG time_to_live, ULONG protocol, ULONG fragment)
{
TX_INTERRUPT_SAVE_AREA
NX_IP_DRIVER driver_request;
NX_IP_HEADER *ip_header_ptr;
#ifndef NX_DISABLE_IP_TX_CHECKSUM
ULONG checksum;
ULONG temp;
#endif /* !NX_DISABLE_IP_TX_CHECKSUM */
UINT index;
NX_ARP *arp_ptr;
NX_PACKET *last_packet;
NX_PACKET *remove_packet;
UINT queued_count;
#ifndef NX_DISABLE_IP_INFO
/* Increment the total send requests counter. */
ip_ptr -> nx_ip_total_packet_send_requests++;
#endif /* !NX_DISABLE_IP_INFO */
/* Prepend the IP header to the packet. First, make room for the IP header. */
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IP_HEADER);
/* Increase the packet length. */
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + sizeof(NX_IP_HEADER);
/* Make sure the packet interface or next hop (e.g. gateway) is set. */
if ((packet_ptr -> nx_packet_ip_interface == NX_NULL) || (packet_ptr -> nx_packet_next_hop_address == 0))
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP invalid packet error. */
ip_ptr -> nx_ip_invalid_transmit_packets++;
#endif /* !NX_DISABLE_IP_INFO */
/* Release the packet. Note that at this point the prepend_ptr points to the beginning of the IP header. */
_nx_packet_transmit_release(packet_ptr);
/* Return... nothing more can be done! */
return;
}
/* If the IP header won't fit, return an error. */
if (packet_ptr -> nx_packet_prepend_ptr < packet_ptr -> nx_packet_data_start)
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP invalid packet error. */
ip_ptr -> nx_ip_invalid_transmit_packets++;
#endif /* !NX_DISABLE_IP_INFO */
/* Release the packet. Note that at this point the prepend_ptr points to the beginning of the IP header. */
_nx_packet_transmit_release(packet_ptr);
/* Return... nothing more can be done! */
return;
}
/* Build the IP header. */
/* Setup the IP header pointer. */
ip_header_ptr = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
/* Build the first 32-bit word of the IP header. */
ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | type_of_service | (0xFFFF & packet_ptr -> nx_packet_length));
/* Build the second 32-bit word of the IP header. */
ip_header_ptr -> nx_ip_header_word_1 = (ip_ptr -> nx_ip_packet_id++ << NX_SHIFT_BY_16) | fragment;
/* Build the third 32-bit word of the IP header. */
ip_header_ptr -> nx_ip_header_word_2 = ((time_to_live << NX_IP_TIME_TO_LIVE_SHIFT) | protocol);
/* Place the source IP address in the IP header. */
ip_header_ptr -> nx_ip_header_source_ip = packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address;
/* Place the destination IP address in the IP header. */
ip_header_ptr -> nx_ip_header_destination_ip = destination_ip;
#ifndef NX_DISABLE_IP_TX_CHECKSUM
/* 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_DISABLE_IP_TX_CHECKSUM */
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IP_SEND, ip_ptr, destination_ip, packet_ptr, packet_ptr -> nx_packet_length, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
swap the endian of the IP header. */
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 NX_ENABLE_IP_PACKET_FILTER
/* Check if the IP packet filter is set. */
if (ip_ptr -> nx_ip_packet_filter)
{
/* Yes, call the IP packet filter routine. */
if ((ip_ptr -> nx_ip_packet_filter((VOID *)(ip_header_ptr), NX_IP_PACKET_OUT)) != NX_SUCCESS)
{
/* Drop the packet. */
_nx_packet_transmit_release(packet_ptr);
return;
}
}
#endif /* NX_ENABLE_IP_PACKET_FILTER */
/* Take care of the loopback case. */
if ((destination_ip == packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address) ||
((destination_ip >= NX_IP_LOOPBACK_FIRST) && (destination_ip <= NX_IP_LOOPBACK_LAST)))
{
/* Send the packet via the loopback driver, and release the original
packet after loopback send. */
_nx_ip_loopback_send(ip_ptr, packet_ptr, NX_TRUE);
return;
}
/* Determine if physical mapping is needed by the link driver. */
if (packet_ptr -> nx_packet_ip_interface -> nx_interface_address_mapping_needed)
{
/* Yes, Check for broadcast address. */
/* Determine if an IP limited or directed broadcast is requested. */
if ((destination_ip == NX_IP_LIMITED_BROADCAST) ||
(((destination_ip & packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask) == packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network) &&
((destination_ip & ~(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask)) == ~(packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_network_mask))))
{
/* Build the driver request. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_PACKET_BROADCAST;
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 = packet_ptr -> nx_packet_ip_interface;
#ifndef NX_DISABLE_FRAGMENTATION
/* Determine if fragmentation is needed. */
if ((packet_ptr -> nx_packet_length) > (packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_mtu_size))
{
/* Fragmentation is needed, call the fragment routine if available. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Call the IP fragment processing routine. */
(ip_ptr -> nx_ip_fragment_processing)(&driver_request);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
/* Just release the packet. */
_nx_packet_transmit_release(packet_ptr);
}
/* In either case, this packet send is complete, just return. */
return;
}
#endif /* !NX_DISABLE_FRAGMENTATION */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif /* !NX_DISABLE_IP_INFO */
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Broadcast packet. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
return;
}
/* Determine if we have a class D multicast address. */
else if ((destination_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE)
{
/* Yes, we have a class D multicast address. Derive the physical mapping from
the class D address. */
driver_request.nx_ip_driver_physical_address_msw = NX_IP_MULTICAST_UPPER;
driver_request.nx_ip_driver_physical_address_lsw = NX_IP_MULTICAST_LOWER | (destination_ip & NX_IP_MULTICAST_MASK);
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
/* Determine if the group was joined by this IP instance, and requested a packet via its loopback interface. */
index = 0;
while (index < NX_MAX_MULTICAST_GROUPS)
{
/* Determine if the destination address matches the requested address. */
if (ip_ptr -> nx_ip_igmp_join_list[index] == destination_ip)
{
/* Yes, break the loop! */
break;
}
/* Increment the join list index. */
index++;
}
if (index < NX_MAX_MULTICAST_GROUPS)
{
/* Determine if the group has loopback enabled. */
if (ip_ptr -> nx_ip_igmp_group_loopback_enable[index])
{
/*
Yes, loopback is enabled! Send the packet via
the loopback interface, and do not release the
original packet so it can be transmitted via a physical
interface later on.
*/
_nx_ip_loopback_send(ip_ptr, packet_ptr, NX_FALSE);
}
}
/* Build the driver request. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_PACKET_SEND;
driver_request.nx_ip_driver_packet = packet_ptr;
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
#ifndef NX_DISABLE_FRAGMENTATION
/* Determine if fragmentation is needed. */
if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_mtu_size)
{
/* Fragmentation is needed, call the fragment routine if available. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Call the IP fragment processing routine. */
(ip_ptr -> nx_ip_fragment_processing)(&driver_request);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
/* Just release the packet. */
_nx_packet_transmit_release(packet_ptr);
}
/* In either case, this packet send is complete, just return. */
return;
}
#endif /* !NX_DISABLE_FRAGMENTATION */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif /* !NX_DISABLE_IP_INFO */
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Send the IP packet out on the network via the attached driver. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
/* Done processing Multicast packet. Return to caller. */
return;
}
/* If we get here, the packet destination is a unicast address. */
destination_ip = packet_ptr -> nx_packet_next_hop_address;
/* Look into the ARP Routing Table to derive the physical address. */
/* Calculate the hash index for the destination IP address. */
index = (UINT)((destination_ip + (destination_ip >> 8)) & NX_ROUTE_TABLE_MASK);
/* Disable interrupts temporarily. */
TX_DISABLE
/* Determine if there is an entry for this IP address. */
arp_ptr = ip_ptr -> nx_ip_arp_table[index];
/* Determine if this arp entry matches the destination IP address. */
if ((arp_ptr) && (arp_ptr -> nx_arp_ip_address == destination_ip))
{
/* Yes, we have an existing ARP mapping entry. */
/* Determine if there is a physical address. */
if (arp_ptr -> nx_arp_physical_address_msw | arp_ptr -> nx_arp_physical_address_lsw)
{
/* Yes, we have a physical mapping. Copy the physical address into the driver
request structure. */
driver_request.nx_ip_driver_physical_address_msw = arp_ptr -> nx_arp_physical_address_msw;
driver_request.nx_ip_driver_physical_address_lsw = arp_ptr -> nx_arp_physical_address_lsw;
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
/* Restore interrupts. */
TX_RESTORE
/* Build the driver request. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_PACKET_SEND;
driver_request.nx_ip_driver_packet = packet_ptr;
#ifndef NX_DISABLE_FRAGMENTATION
/* Determine if fragmentation is needed. */
if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_mtu_size)
{
/* Fragmentation is needed, call the fragment routine if available. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Call the IP fragment processing routine. */
(ip_ptr -> nx_ip_fragment_processing)(&driver_request);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
/* Just release the packet. */
_nx_packet_transmit_release(packet_ptr);
}
/* In either case, this packet send is complete, just return. */
return;
}
#endif /* !NX_DISABLE_FRAGMENTATION */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif /* !NX_DISABLE_IP_INFO */
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Send the IP packet out on the network via the attached driver. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
/* Return to caller. */
return;
}
else
{
/* No physical mapping available. Set the current packet's queue next pointer to NULL. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Determine if the queue is empty. */
if (arp_ptr -> nx_arp_packets_waiting == NX_NULL)
{
/* Yes, we have an empty ARP packet queue. Simply place the
packet at the head of the list. */
arp_ptr -> nx_arp_packets_waiting = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Determine how many packets are on the ARP entry's packet
queue and remember the last packet in the queue. We know
there is at least one on the queue and another that is
going to be queued. */
last_packet = arp_ptr -> nx_arp_packets_waiting;
queued_count = 1;
while (last_packet -> nx_packet_queue_next)
{
/* Increment the queued count. */
queued_count++;
/* Yes, move to the next packet in the queue. */
last_packet = last_packet -> nx_packet_queue_next;
}
/* Place the packet at the end of the list. */
last_packet -> nx_packet_queue_next = packet_ptr;
/* Default the remove packet pointer to NULL. */
remove_packet = NX_NULL;
/* Determine if the packets queued has exceeded the queue
depth. */
if (queued_count >= NX_ARP_MAX_QUEUE_DEPTH)
{
/* Save the packet pointer at the head of the list. */
remove_packet = arp_ptr -> nx_arp_packets_waiting;
/* Remove the packet from the ARP queue. */
arp_ptr -> nx_arp_packets_waiting = remove_packet -> nx_packet_queue_next;
/* Clear the remove packet queue next pointer. */
remove_packet -> nx_packet_queue_next = NX_NULL;
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP transmit resource error count. */
ip_ptr -> nx_ip_transmit_resource_errors++;
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
}
/* Restore interrupts. */
TX_RESTORE
/* Determine if there is a packet to remove. */
if (remove_packet)
{
/* Yes, the packet queue depth for this ARP entry was exceeded
so release the packet that was removed from the queue. */
_nx_packet_transmit_release(remove_packet);
}
}
/* Return to caller. */
return;
}
}
else
{
/* At this point, we need to search the ARP list for a match for the
destination IP. */
/* First, restore interrupts. */
TX_RESTORE
/* Pickup the first ARP entry. */
arp_ptr = ip_ptr -> nx_ip_arp_table[index];
/* Loop to look for an ARP match. */
while (arp_ptr)
{
/* Check for an IP match. */
if (arp_ptr -> nx_arp_ip_address == destination_ip)
{
/* Yes, we found a match. Get out of the loop! */
break;
}
/* 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_ptr -> nx_ip_arp_table[index])
{
/* Clear the ARP pointer. */
arp_ptr = NX_NULL;
break;
}
}
/* Determine if we actually found a matching ARP entry. */
if (arp_ptr)
{
/* Yes, we found an ARP entry. Now check and see if
it has an actual physical address. */
if (arp_ptr -> nx_arp_physical_address_msw | arp_ptr -> nx_arp_physical_address_lsw)
{
/* Yes, we have a physical mapping. Copy the physical address into the driver
request structure. */
driver_request.nx_ip_driver_physical_address_msw = arp_ptr -> nx_arp_physical_address_msw;
driver_request.nx_ip_driver_physical_address_lsw = arp_ptr -> nx_arp_physical_address_lsw;
/* Disable interrupts. */
TX_DISABLE
/* Move this ARP entry to the head of the list. */
ip_ptr -> nx_ip_arp_table[index] = arp_ptr;
/* Restore interrupts. */
TX_RESTORE
/* Build the driver request message. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_PACKET_SEND;
driver_request.nx_ip_driver_packet = packet_ptr;
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
#ifndef NX_DISABLE_FRAGMENTATION
/* Determine if fragmentation is needed. */
if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_mtu_size)
{
/* Fragmentation is needed, call the fragment routine if available. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Call the IP fragment processing routine. */
(ip_ptr -> nx_ip_fragment_processing)(&driver_request);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
/* Just release the packet. */
_nx_packet_transmit_release(packet_ptr);
}
/* In either case, this packet send is complete, just return. */
return;
}
#endif /* !NX_DISABLE_FRAGMENTATION */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif /* !NX_DISABLE_IP_INFO */
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Send the IP packet out on the network via the attached driver. */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
/* Return to caller. */
return;
}
else
{
/* We don't have physical mapping. */
/* Disable interrupts. */
TX_DISABLE
/* Ensure the current packet's queue next pointer to NULL. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Determine if the queue is empty. */
if (arp_ptr -> nx_arp_packets_waiting == NX_NULL)
{
/* Yes, we have an empty ARP packet queue. Simply place the
packet at the head of the list. */
arp_ptr -> nx_arp_packets_waiting = packet_ptr;
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Determine how many packets are on the ARP entry's packet
queue and remember the last packet in the queue. We know
there is at least one on the queue and another that is
going to be queued. */
last_packet = arp_ptr -> nx_arp_packets_waiting;
queued_count = 1;
while (last_packet -> nx_packet_queue_next)
{
/* Increment the queued count. */
queued_count++;
/* Yes, move to the next packet in the queue. */
last_packet = last_packet -> nx_packet_queue_next;
}
/* Place the packet at the end of the list. */
last_packet -> nx_packet_queue_next = packet_ptr;
/* Default the remove packet pointer to NULL. */
remove_packet = NX_NULL;
/* Determine if the packets queued has exceeded the queue
depth. */
if (queued_count >= NX_ARP_MAX_QUEUE_DEPTH)
{
/* Save the packet pointer at the head of the list. */
remove_packet = arp_ptr -> nx_arp_packets_waiting;
/* Remove the packet from the ARP queue. */
arp_ptr -> nx_arp_packets_waiting = remove_packet -> nx_packet_queue_next;
/* Clear the remove packet queue next pointer. */
remove_packet -> nx_packet_queue_next = NX_NULL;
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP transmit resource error count. */
ip_ptr -> nx_ip_transmit_resource_errors++;
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
}
/* Restore interrupts. */
TX_RESTORE
/* Determine if there is a packet to remove. */
if (remove_packet)
{
/* Yes, the packet queue depth for this ARP entry was exceeded
so release the packet that was removed from the queue. */
_nx_packet_transmit_release(remove_packet);
}
}
/* Return to caller. */
return;
}
}
else
{
/* No ARP entry was found. We need to allocate a new ARP entry, populate it, and
initiate an ARP request to get the specific physical mapping. */
/* Allocate a new ARP entry. */
if ((!ip_ptr -> nx_ip_arp_allocate) ||
((ip_ptr -> nx_ip_arp_allocate)(ip_ptr, &(ip_ptr -> nx_ip_arp_table[index]))))
{
/* Error, release the protection and the packet. */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP transmit resource error count. */
ip_ptr -> nx_ip_transmit_resource_errors++;
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
/* Release the packet. */
_nx_packet_transmit_release(packet_ptr);
/* Just return! */
return;
}
/* Otherwise, setup a pointer to the new ARP entry. */
arp_ptr = (ip_ptr -> nx_ip_arp_table[index]) -> nx_arp_active_previous;
/* Setup the IP address and clear the physical mapping. */
arp_ptr -> nx_arp_ip_address = destination_ip;
arp_ptr -> nx_arp_physical_address_msw = 0;
arp_ptr -> nx_arp_physical_address_lsw = 0;
arp_ptr -> nx_arp_entry_next_update = NX_ARP_UPDATE_RATE;
arp_ptr -> nx_arp_retries = 0;
arp_ptr -> nx_arp_ip_interface = packet_ptr -> nx_packet_ip_interface;
/* Ensure the queue next pointer is NULL for the packet before it
is placed on the ARP waiting queue. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Queue the packet for output. */
arp_ptr -> nx_arp_packets_waiting = packet_ptr;
/* Call ARP send to send an ARP request. */
(ip_ptr -> nx_ip_arp_packet_send)(ip_ptr, destination_ip, packet_ptr -> nx_packet_ip_interface);
return;
}
}
}
else
{
/* This IP interface does not require any IP-to-physical mapping. */
/* Build the driver request. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_PACKET_SEND;
driver_request.nx_ip_driver_packet = packet_ptr;
driver_request.nx_ip_driver_interface = packet_ptr -> nx_packet_ip_interface;
#ifndef NX_DISABLE_FRAGMENTATION
/* Determine if fragmentation is needed. */
if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_mtu_size)
{
/* Fragmentation is needed, call the fragment routine if available. */
if (ip_ptr -> nx_ip_fragment_processing)
{
/* Call the IP fragment processing routine. */
(ip_ptr -> nx_ip_fragment_processing)(&driver_request);
}
else
{
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP send packets dropped count. */
ip_ptr -> nx_ip_send_packets_dropped++;
#endif /* !NX_DISABLE_IP_INFO */
/* Just release the packet. */
_nx_packet_transmit_release(packet_ptr);
}
/* In either case, this packet send is complete, just return. */
return;
}
#endif /* !NX_DISABLE_FRAGMENTATION */
#ifndef NX_DISABLE_IP_INFO
/* Increment the IP packet sent count. */
ip_ptr -> nx_ip_total_packets_sent++;
/* Increment the IP bytes sent count. */
ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - sizeof(NX_IP_HEADER);
#endif /* !NX_DISABLE_IP_INFO */
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0)
/* No mapping driver. Just send the packet out! */
(packet_ptr -> nx_packet_ip_interface -> nx_interface_link_driver_entry) (&driver_request);
}
}

View File

@ -0,0 +1,85 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_periodic_timer_entry PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles waking up the IP helper thread on a periodic */
/* basis. Periodic IP processing includes ARP requests, IP fragment */
/* timeouts, and TCP timeouts. All of which are driven from this */
/* single periodic timer. */
/* */
/* INPUT */
/* */
/* ip_address IP address in a ULONG */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* tx_event_flags_set Set event flags to wakeup */
/* IP helper thread */
/* */
/* CALLED BY */
/* */
/* ThreadX system timer thread */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_periodic_timer_entry(ULONG ip_address)
{
NX_IP *ip_ptr;
/* Convert input parameter to an IP pointer. */
ip_ptr = (NX_IP *)ip_address;
/* Wakeup this IP's helper thread. */
tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_PERIODIC_EVENT, TX_OR);
}

View File

@ -0,0 +1,160 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_raw_packet_cleanup PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes raw packet receive timeout and thread */
/* terminate actions that require the IP data structures to be */
/* cleaned up to remove the suspended thread. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to suspended thread's */
/* control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_system_resume Resume thread service */
/* */
/* CALLED BY */
/* */
/* _nx_ip_delete Delete IP instance */
/* _nx_ip_raw_packet_disable Disable raw packet processing */
/* _tx_thread_timeout Thread timeout processing */
/* _tx_thread_terminate Thread terminate processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_raw_packet_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER)
{
TX_INTERRUPT_SAVE_AREA
NX_IP *ip_ptr; /* Working IP pointer */
NX_CLEANUP_EXTENSION
/* Setup pointer to the IP control block. */
ip_ptr = (NX_IP *)thread_ptr -> tx_thread_suspend_control_block;
/* Disable interrupts to remove the suspended thread from the block pool. */
TX_DISABLE
/* Determine if the cleanup is still required. */
if ((thread_ptr -> tx_thread_suspend_cleanup) && (ip_ptr) &&
(ip_ptr -> nx_ip_id == NX_IP_ID))
{
/* Yes, we still have thread suspension! */
/* Clear the suspension cleanup flag. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Remove the suspended thread from the list. */
/* See if this is the only suspended thread on the list. */
if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
ip_ptr -> nx_ip_raw_packet_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same suspension list. */
/* Update the list head pointer. */
ip_ptr -> nx_ip_raw_packet_suspension_list = thread_ptr -> tx_thread_suspended_next;
/* Update the links of the adjacent threads. */
(thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
thread_ptr -> tx_thread_suspended_previous;
(thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
thread_ptr -> tx_thread_suspended_next;
}
/* Decrement the suspension count. */
ip_ptr -> nx_ip_raw_packet_suspended_count--;
/* Now we need to determine if this cleanup is from a terminate, timeout,
or from a wait abort. */
if (thread_ptr -> tx_thread_state == TX_TCP_IP)
{
/* Thread still suspended on the packet pool. Setup return error status and
resume the thread. */
/* Setup return status. */
thread_ptr -> tx_thread_suspend_status = NX_NO_PACKET;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread! Check for preemption even though we are executing
from the system timer thread right now which normally executes at the
highest priority. */
_tx_thread_system_resume(thread_ptr);
/* Finished, just return. */
return;
}
}
/* Restore interrupts. */
TX_RESTORE
}

View File

@ -0,0 +1,150 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_raw_packet_disable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function disables raw IP packet sending and receiving. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _nx_packet_release Release data packet */
/* _nx_ip_raw_packet_cleanup Release suspended threads */
/* _tx_thread_system_preempt_check Check for preemption */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_raw_packet_disable(NX_IP *ip_ptr)
{
TX_INTERRUPT_SAVE_AREA
NX_PACKET *current_packet;
NX_PACKET *next_packet;
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_RAW_PACKET_DISABLE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Disable interrupts. */
TX_DISABLE
/* Disable raw IP packet sending/receiving. */
ip_ptr -> nx_ip_raw_ip_processing = NX_NULL;
/* Pickup the head pointer to any raw IP packets queued up. */
next_packet = ip_ptr -> nx_ip_raw_received_packet_head;
/* Clear the head and tail pointers. */
ip_ptr -> nx_ip_raw_received_packet_head = NX_NULL;
ip_ptr -> nx_ip_raw_received_packet_tail = NX_NULL;
ip_ptr -> nx_ip_raw_received_packet_count = 0;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Loop to release any queued up raw IP packets. */
while (next_packet)
{
/* Setup the current packet pointer. */
current_packet = next_packet;
/* Move to the next packet. */
next_packet = next_packet -> nx_packet_queue_next;
/* Release the current packet. */
_nx_packet_release(current_packet);
}
/* Lift any suspension on RAW IP packet receives. */
while (ip_ptr -> nx_ip_raw_packet_suspension_list)
{
/* Release the suspended thread. */
_nx_ip_raw_packet_cleanup(ip_ptr -> nx_ip_raw_packet_suspension_list NX_CLEANUP_ARGUMENT);
}
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Disable interrupts. */
TX_DISABLE
/* Restore preemption. */
_tx_thread_preempt_disable--;
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_raw_packet_enable PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets the function pointer to enable raw IP packet */
/* sending and receiving. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_raw_packet_enable(NX_IP *ip_ptr)
{
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_RAW_PACKET_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0)
/* Enable raw IP packet sending/receiving. */
ip_ptr -> nx_ip_raw_ip_processing = _nx_ip_raw_packet_processing;
/* Return a successful status! */
return(NX_SUCCESS);
}

View File

@ -0,0 +1,123 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_raw_packet_interface_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sends a raw IP packet through the specified IP */
/* interface. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* destination_ip Destination IP address */
/* interface_index Network interface to use */
/* type_of_service Type of service for packet */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* nx_ip_packet_send Core IP packet send service */
/* nx_ip_route_find Find a suitable outgoing */
/* interface. */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_raw_packet_interface_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
ULONG destination_ip, UINT interface_index, ULONG type_of_service)
{
/* Determine if raw IP packet sending/receiving is enabled. */
if (ip_ptr -> nx_ip_raw_ip_processing)
{
/* Store interface information into the packet structure. */
packet_ptr -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]);
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Figure out a suitable outgoing interface. */
if (_nx_ip_route_find(ip_ptr, destination_ip, &packet_ptr -> nx_packet_ip_interface, &packet_ptr -> nx_packet_next_hop_address) != NX_SUCCESS)
{
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
return(NX_IP_ADDRESS_ERROR);
}
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_RAW_PACKET_SEND, ip_ptr, packet_ptr, destination_ip, type_of_service, NX_TRACE_IP_EVENTS, 0, 0)
/* Yes, raw packet sending and receiving is enabled send packet! */
_nx_ip_packet_send(ip_ptr, packet_ptr, destination_ip, type_of_service, NX_IP_TIME_TO_LIVE, NX_IP_UDP, NX_FRAGMENT_OKAY);
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return a successful status! */
return(NX_SUCCESS);
}
else
{
/* Return an error. */
return(NX_NOT_ENABLED);
}
}

View File

@ -0,0 +1,175 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_raw_packet_processing PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes a received raw IP packet from the */
/* _nx_ip_packet_receive function and either queues it or gives it to */
/* the first suspended thread waiting for a raw IP packet. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_system_resume Resume suspended thread */
/* */
/* CALLED BY */
/* */
/* _nx_ip_packet_receive Packet receive processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _nx_ip_raw_packet_processing(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
/* Determine if there is a thread waiting for the IP packet. If so, just
give the packet to the waiting thread. */
thread_ptr = ip_ptr -> nx_ip_raw_packet_suspension_list;
if (thread_ptr)
{
/* Disable interrupts. */
TX_DISABLE
/* Yes, a thread is suspended on the raw IP packet queue. */
/* See if this is the only suspended thread on the list. */
if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
ip_ptr -> nx_ip_raw_packet_suspension_list = NX_NULL;
}
else
{
/* At least one more thread is on the same expiration list. */
/* Update the list head pointer. */
ip_ptr -> nx_ip_raw_packet_suspension_list = thread_ptr -> tx_thread_suspended_next;
/* Update the links of the adjacent threads. */
(thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
thread_ptr -> tx_thread_suspended_previous;
(thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
thread_ptr -> tx_thread_suspended_next;
}
/* Decrement the suspension count. */
ip_ptr -> nx_ip_raw_packet_suspended_count--;
/* Prepare for resumption of the first thread. */
/* Clear cleanup routine to avoid timeout. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Return this packet pointer to the suspended thread waiting for
a block. */
*((NX_PACKET **)thread_ptr -> tx_thread_additional_suspend_info) = packet_ptr;
/* Put return status into the thread control block. */
thread_ptr -> tx_thread_suspend_status = NX_SUCCESS;
/* Resume thread. */
_tx_thread_system_resume(thread_ptr);
}
else
{
/* Disable interrupts. */
TX_DISABLE
/* Otherwise, queue the raw IP packet in a FIFO manner on the raw packet list. */
/* Clear the next packet pointer. */
packet_ptr -> nx_packet_queue_next = NX_NULL;
/* Determine if the queue is empty. */
if (ip_ptr -> nx_ip_raw_received_packet_tail)
{
/* List is not empty, place the raw packet at the end of the raw packet list. */
(ip_ptr -> nx_ip_raw_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
ip_ptr -> nx_ip_raw_received_packet_tail = packet_ptr;
}
else
{
/* This is the first entry on the queue so set the head and tail pointers. */
ip_ptr -> nx_ip_raw_received_packet_head = packet_ptr;
ip_ptr -> nx_ip_raw_received_packet_tail = packet_ptr;
}
/* Increment the raw packet received count. */
ip_ptr -> nx_ip_raw_received_packet_count++;
/* Restore interrupts. */
TX_RESTORE
}
}

View File

@ -0,0 +1,212 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "tx_thread.h"
#include "nx_ip.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_raw_packet_receive PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves the first packet from the received raw */
/* packet list and returns it to the caller. If no packet is present */
/* the routine may optionally suspend waiting on the list for a */
/* packet. */
/* */
/* INPUT */
/* */
/* ip_ptr IP control block pointer */
/* packet_ptr Pointer to return allocated */
/* packet */
/* wait_option Suspension option */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_suspend Suspend thread */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_raw_packet_receive(NX_IP *ip_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
{
TX_INTERRUPT_SAVE_AREA
UINT status; /* Return status */
TX_THREAD *thread_ptr; /* Working thread pointer */
NX_PACKET *work_ptr; /* Working packet pointer */
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *trace_event;
ULONG trace_timestamp;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_RAW_PACKET_RECEIVE, ip_ptr, 0, wait_option, 0, NX_TRACE_IP_EVENTS, &trace_event, &trace_timestamp)
/* Disable interrupts to get a packet from the pool. */
TX_DISABLE
/* Determine if there is an available packet. */
if (ip_ptr -> nx_ip_raw_received_packet_count)
{
/* Yes, a packet is available. Decrement the raw packet receive count. */
ip_ptr -> nx_ip_raw_received_packet_count--;
/* Pickup the first raw packet pointer. */
work_ptr = ip_ptr -> nx_ip_raw_received_packet_head;
/* Modify the available list to point at the next packet in the pool. */
ip_ptr -> nx_ip_raw_received_packet_head = work_ptr -> nx_packet_queue_next;
/* Determine if the tail pointer points to the same packet. */
if (ip_ptr -> nx_ip_raw_received_packet_tail == work_ptr)
{
/* Yes, just set tail pointer to NULL since we must be at the end of the queue. */
ip_ptr -> nx_ip_raw_received_packet_tail = NX_NULL;
}
/* Place the raw packet pointer in the return destination. */
*packet_ptr = work_ptr;
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_IP_RAW_PACKET_RECEIVE, 0, *packet_ptr, 0, 0)
/* Set status to success. */
status = NX_SUCCESS;
}
else
{
/* Determine if the request specifies suspension. */
if (wait_option)
{
/* Prepare for suspension of this thread. */
/* Pickup thread pointer. */
thread_ptr = _tx_thread_current_ptr;
/* Setup cleanup routine pointer. */
thread_ptr -> tx_thread_suspend_cleanup = _nx_ip_raw_packet_cleanup;
/* Setup cleanup information, i.e. this IP control
block. */
thread_ptr -> tx_thread_suspend_control_block = (void *)ip_ptr;
/* Save the return packet pointer address as well. */
thread_ptr -> tx_thread_additional_suspend_info = (void *)packet_ptr;
/* Setup suspension list. */
if (ip_ptr -> nx_ip_raw_packet_suspension_list)
{
/* This list is not NULL, add current thread to the end. */
thread_ptr -> tx_thread_suspended_next =
ip_ptr -> nx_ip_raw_packet_suspension_list;
thread_ptr -> tx_thread_suspended_previous =
(ip_ptr -> nx_ip_raw_packet_suspension_list) -> tx_thread_suspended_previous;
((ip_ptr -> nx_ip_raw_packet_suspension_list) -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
thread_ptr;
(ip_ptr -> nx_ip_raw_packet_suspension_list) -> tx_thread_suspended_previous = thread_ptr;
}
else
{
/* No other threads are suspended. Setup the head pointer and
just setup this threads pointers to itself. */
ip_ptr -> nx_ip_raw_packet_suspension_list = thread_ptr;
thread_ptr -> tx_thread_suspended_next = thread_ptr;
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
}
/* Increment the suspended thread count. */
ip_ptr -> nx_ip_raw_packet_suspended_count++;
/* Set the state to suspended. */
thread_ptr -> tx_thread_state = TX_TCP_IP;
/* Set the suspending flag. */
thread_ptr -> tx_thread_suspending = TX_TRUE;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Save the timeout value. */
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
/* Restore interrupts. */
TX_RESTORE
/* Call actual thread suspension routine. */
_tx_thread_system_suspend(thread_ptr);
/* Update the trace event with the status. */
NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_IP_RAW_PACKET_RECEIVE, 0, *packet_ptr, 0, 0)
/* Return the completion status. */
return(thread_ptr -> tx_thread_suspend_status);
}
else
{
/* Immediate return, return error completion. */
status = NX_NO_PACKET;
}
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,119 @@
/**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** NetX Component */
/** */
/** Internet Protocol (IP) */
/** */
/**************************************************************************/
/**************************************************************************/
#define NX_SOURCE_CODE
/* Include necessary system files. */
#include "nx_api.h"
#include "nx_ip.h"
#include "nx_packet.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_ip_raw_packet_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sends a raw IP packet through the specified IP */
/* interface. */
/* */
/* INPUT */
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
/* destination_ip Destination IP address */
/* type_of_service Type of service for packet */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* nx_ip_packet_send Core IP packet send service */
/* nx_ip_route_find Find a suitable outgoing */
/* interface. */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _nx_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
ULONG destination_ip, ULONG type_of_service)
{
/* Determine if raw IP packet sending/receiving is enabled. */
if (ip_ptr -> nx_ip_raw_ip_processing)
{
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
/* Figure out a suitable outgoing interface. */
if (_nx_ip_route_find(ip_ptr, destination_ip, &packet_ptr -> nx_packet_ip_interface, &packet_ptr -> nx_packet_next_hop_address) != NX_SUCCESS)
{
/* Release the protection on the ARP list. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
return(NX_IP_ADDRESS_ERROR);
}
/* If trace is enabled, insert this event into the trace buffer. */
NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_RAW_PACKET_SEND, ip_ptr, packet_ptr, destination_ip, type_of_service, NX_TRACE_IP_EVENTS, 0, 0)
/* Yes, raw packet sending and receiving is enabled send packet! */
_nx_ip_packet_send(ip_ptr, packet_ptr, destination_ip, type_of_service, NX_IP_TIME_TO_LIVE, NX_IP_RAW, NX_FRAGMENT_OKAY);
/* Release mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return a successful status! */
return(NX_SUCCESS);
}
else
{
/* Return an error. */
return(NX_NOT_ENABLED);
}
}

Some files were not shown because too many files have changed in this diff Show More