mirror of
https://github.com/azure-rtos/netx.git
synced 2023-08-10 07:57:54 +08:00
Initial commit
This commit is contained in:
commit
e0f67c0550
40
.gitattributes
vendored
Normal file
40
.gitattributes
vendored
Normal 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
14
.gitignore
vendored
Executable 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
49
CMakeLists.txt
Executable 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
246
LICENSE.txt
Normal 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 Microsoft’s 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
|
||||||
|
Microsoft’s 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 Microsoft’s 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
|
||||||
|
Microsoft’s 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
|
||||||
|
n’accorde 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, d’adéquation à un usage particulier
|
||||||
|
et d’absence 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 d’une autre faute dans la limite
|
||||||
|
autorisée par la loi en vigueur.
|
||||||
|
|
||||||
|
Elle s’applique également, même si Microsoft connaissait ou devrait connaître
|
||||||
|
l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la
|
||||||
|
limitation de responsabilité pour les dommages indirects, accessoires ou de
|
||||||
|
quelque nature que ce soit, il se peut que la limitation ou l’exclusion
|
||||||
|
ci-dessus ne s’appliquera pas à votre égard.
|
||||||
|
|
||||||
|
EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous
|
||||||
|
pourriez avoir d’autres 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
16
LICENSED-HARDWARE.txt
Normal 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.
|
321
common/CMakeLists.txt
Normal file
321
common/CMakeLists.txt
Normal 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
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
154
common/inc/nx_arp.h
Normal 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
186
common/inc/nx_icmp.h
Normal 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
211
common/inc/nx_igmp.h
Normal 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
300
common/inc/nx_ip.h
Normal 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
146
common/inc/nx_packet.h
Normal 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
115
common/inc/nx_rarp.h
Normal 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
152
common/inc/nx_system.h
Normal 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
446
common/inc/nx_tcp.h
Normal 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
167
common/inc/nx_udp.h
Normal 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
484
common/inc/nx_user_sample.h
Normal 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
|
||||||
|
|
162
common/src/nx_arp_announce_send.c
Normal file
162
common/src/nx_arp_announce_send.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
202
common/src/nx_arp_dynamic_entries_invalidate.c
Normal file
202
common/src/nx_arp_dynamic_entries_invalidate.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
306
common/src/nx_arp_dynamic_entry_set.c
Normal file
306
common/src/nx_arp_dynamic_entry_set.c
Normal 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
150
common/src/nx_arp_enable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
230
common/src/nx_arp_entry_allocate.c
Normal file
230
common/src/nx_arp_entry_allocate.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
107
common/src/nx_arp_gratuitous_send.c
Normal file
107
common/src/nx_arp_gratuitous_send.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
213
common/src/nx_arp_hardware_address_find.c
Normal file
213
common/src/nx_arp_hardware_address_find.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
170
common/src/nx_arp_info_get.c
Normal file
170
common/src/nx_arp_info_get.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
211
common/src/nx_arp_ip_address_find.c
Normal file
211
common/src/nx_arp_ip_address_find.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
134
common/src/nx_arp_packet_deferred_receive.c
Normal file
134
common/src/nx_arp_packet_deferred_receive.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
630
common/src/nx_arp_packet_receive.c
Normal file
630
common/src/nx_arp_packet_receive.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
152
common/src/nx_arp_packet_send.c
Normal file
152
common/src/nx_arp_packet_send.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
273
common/src/nx_arp_periodic_update.c
Normal file
273
common/src/nx_arp_periodic_update.c
Normal 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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
165
common/src/nx_arp_probe_send.c
Normal file
165
common/src/nx_arp_probe_send.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
108
common/src/nx_arp_queue_process.c
Normal file
108
common/src/nx_arp_queue_process.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
127
common/src/nx_arp_static_entries_delete.c
Normal file
127
common/src/nx_arp_static_entries_delete.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
309
common/src/nx_arp_static_entry_create.c
Normal file
309
common/src/nx_arp_static_entry_create.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
259
common/src/nx_arp_static_entry_delete.c
Normal file
259
common/src/nx_arp_static_entry_delete.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
182
common/src/nx_icmp_checksum_compute.c
Normal file
182
common/src/nx_icmp_checksum_compute.c
Normal 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
|
||||||
|
|
168
common/src/nx_icmp_cleanup.c
Normal file
168
common/src/nx_icmp_cleanup.c
Normal 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
|
||||||
|
}
|
||||||
|
|
85
common/src/nx_icmp_enable.c
Normal file
85
common/src/nx_icmp_enable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
149
common/src/nx_icmp_info_get.c
Normal file
149
common/src/nx_icmp_info_get.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
340
common/src/nx_icmp_packet_process.c
Normal file
340
common/src/nx_icmp_packet_process.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
193
common/src/nx_icmp_packet_receive.c
Normal file
193
common/src/nx_icmp_packet_receive.c
Normal 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
307
common/src/nx_icmp_ping.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
106
common/src/nx_icmp_queue_process.c
Normal file
106
common/src/nx_icmp_queue_process.c
Normal 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
102
common/src/nx_igmp_enable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
128
common/src/nx_igmp_info_get.c
Normal file
128
common/src/nx_igmp_info_get.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
226
common/src/nx_igmp_interface_report_send.c
Normal file
226
common/src/nx_igmp_interface_report_send.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
83
common/src/nx_igmp_loopback_disable.c
Normal file
83
common/src/nx_igmp_loopback_disable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
83
common/src/nx_igmp_loopback_enable.c
Normal file
83
common/src/nx_igmp_loopback_enable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
104
common/src/nx_igmp_multicast_check.c
Normal file
104
common/src/nx_igmp_multicast_check.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
181
common/src/nx_igmp_multicast_interface_join.c
Normal file
181
common/src/nx_igmp_multicast_interface_join.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
77
common/src/nx_igmp_multicast_join.c
Normal file
77
common/src/nx_igmp_multicast_join.c
Normal 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));
|
||||||
|
}
|
||||||
|
|
188
common/src/nx_igmp_multicast_leave.c
Normal file
188
common/src/nx_igmp_multicast_leave.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
360
common/src/nx_igmp_packet_process.c
Normal file
360
common/src/nx_igmp_packet_process.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
146
common/src/nx_igmp_packet_receive.c
Normal file
146
common/src/nx_igmp_packet_receive.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
155
common/src/nx_igmp_periodic_processing.c
Normal file
155
common/src/nx_igmp_periodic_processing.c
Normal 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
103
common/src/nx_igmp_queue_process.c
Normal file
103
common/src/nx_igmp_queue_process.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
96
common/src/nx_ip_address_change_notify.c
Normal file
96
common/src/nx_ip_address_change_notify.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
95
common/src/nx_ip_address_get.c
Normal file
95
common/src/nx_ip_address_get.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
126
common/src/nx_ip_address_set.c
Normal file
126
common/src/nx_ip_address_set.c
Normal 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
270
common/src/nx_ip_create.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
102
common/src/nx_ip_deferred_link_status_process.c
Normal file
102
common/src/nx_ip_deferred_link_status_process.c
Normal 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
336
common/src/nx_ip_delete.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
94
common/src/nx_ip_delete_queue_clear.c
Normal file
94
common/src/nx_ip_delete_queue_clear.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
98
common/src/nx_ip_driver_deferred_enable.c
Normal file
98
common/src/nx_ip_driver_deferred_enable.c
Normal 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
|
||||||
|
}
|
||||||
|
|
83
common/src/nx_ip_driver_deferred_processing.c
Normal file
83
common/src/nx_ip_driver_deferred_processing.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
118
common/src/nx_ip_driver_deferred_receive.c
Normal file
118
common/src/nx_ip_driver_deferred_receive.c
Normal 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
|
||||||
|
}
|
||||||
|
|
108
common/src/nx_ip_driver_direct_command.c
Normal file
108
common/src/nx_ip_driver_direct_command.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
108
common/src/nx_ip_driver_interface_direct_command.c
Normal file
108
common/src/nx_ip_driver_interface_direct_command.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
85
common/src/nx_ip_driver_link_status_event.c
Normal file
85
common/src/nx_ip_driver_link_status_event.c
Normal 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
|
||||||
|
}
|
||||||
|
|
97
common/src/nx_ip_forward_packet_process.c
Normal file
97
common/src/nx_ip_forward_packet_process.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
91
common/src/nx_ip_forwarding_disable.c
Normal file
91
common/src/nx_ip_forwarding_disable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
91
common/src/nx_ip_forwarding_enable.c
Normal file
91
common/src/nx_ip_forwarding_enable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
481
common/src/nx_ip_fragment_assembly.c
Normal file
481
common/src/nx_ip_fragment_assembly.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
157
common/src/nx_ip_fragment_disable.c
Normal file
157
common/src/nx_ip_fragment_disable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
98
common/src/nx_ip_fragment_enable.c
Normal file
98
common/src/nx_ip_fragment_enable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
351
common/src/nx_ip_fragment_packet.c
Normal file
351
common/src/nx_ip_fragment_packet.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
136
common/src/nx_ip_fragment_timeout_check.c
Normal file
136
common/src/nx_ip_fragment_timeout_check.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
161
common/src/nx_ip_gateway_address_set.c
Normal file
161
common/src/nx_ip_gateway_address_set.c
Normal 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
190
common/src/nx_ip_info_get.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
83
common/src/nx_ip_initialize.c
Normal file
83
common/src/nx_ip_initialize.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
107
common/src/nx_ip_interface_address_get.c
Normal file
107
common/src/nx_ip_interface_address_get.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
141
common/src/nx_ip_interface_address_set.c
Normal file
141
common/src/nx_ip_interface_address_set.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
176
common/src/nx_ip_interface_attach.c
Normal file
176
common/src/nx_ip_interface_attach.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
133
common/src/nx_ip_interface_info_get.c
Normal file
133
common/src/nx_ip_interface_info_get.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
320
common/src/nx_ip_interface_status_check.c
Normal file
320
common/src/nx_ip_interface_status_check.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
90
common/src/nx_ip_link_status_change_notify_set.c
Normal file
90
common/src/nx_ip_link_status_change_notify_set.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
120
common/src/nx_ip_loopback_send.c
Normal file
120
common/src/nx_ip_loopback_send.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
111
common/src/nx_ip_packet_deferred_receive.c
Normal file
111
common/src/nx_ip_packet_deferred_receive.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
785
common/src/nx_ip_packet_receive.c
Normal file
785
common/src/nx_ip_packet_receive.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
876
common/src/nx_ip_packet_send.c
Normal file
876
common/src/nx_ip_packet_send.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
85
common/src/nx_ip_periodic_timer_entry.c
Normal file
85
common/src/nx_ip_periodic_timer_entry.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
160
common/src/nx_ip_raw_packet_cleanup.c
Normal file
160
common/src/nx_ip_raw_packet_cleanup.c
Normal 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
|
||||||
|
}
|
||||||
|
|
150
common/src/nx_ip_raw_packet_disable.c
Normal file
150
common/src/nx_ip_raw_packet_disable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
83
common/src/nx_ip_raw_packet_enable.c
Normal file
83
common/src/nx_ip_raw_packet_enable.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
123
common/src/nx_ip_raw_packet_interface_send.c
Normal file
123
common/src/nx_ip_raw_packet_interface_send.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
175
common/src/nx_ip_raw_packet_processing.c
Normal file
175
common/src/nx_ip_raw_packet_processing.c
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
212
common/src/nx_ip_raw_packet_receive.c
Normal file
212
common/src/nx_ip_raw_packet_receive.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
119
common/src/nx_ip_raw_packet_send.c
Normal file
119
common/src/nx_ip_raw_packet_send.c
Normal 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
Loading…
x
Reference in New Issue
Block a user