1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** User Datagram Protocol (UDP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "tx_thread.h"
29 #include "nx_udp.h"
30 #include "nx_packet.h"
31 #include "nx_ip.h"
32 #ifdef FEATURE_NX_IPV6
33 #include "nx_ipv6.h"
34 #endif /* FEATURE_NX_IPV6 */
35
36
37 #ifdef NX_ENABLE_TCPIP_OFFLOAD
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _nx_udp_socket_driver_packet_receive PORTABLE C */
43 /* 6.1.8 */
44 /* AUTHOR */
45 /* */
46 /* Yuxin Zhou, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function receives a UDP packet from the TCP/IP driver and add */
51 /* fake TCP/IP header. Then pass the packet to IP deferred receive */
52 /* routine. */
53 /* */
54 /* INPUT */
55 /* */
56 /* socket_ptr Pointer to owning socket */
57 /* packet_ptr Pointer to packet to process */
58 /* local_ip Pointer to local IP address */
59 /* remote_ip Pointer to remote IP address */
60 /* remote_port Pointer to remote UDP port */
61 /* */
62 /* OUTPUT */
63 /* */
64 /* None */
65 /* */
66 /* CALLS */
67 /* */
68 /* tx_mutex_get Obtain protection mutex */
69 /* tx_mutex_put Release protection mutex */
70 /* _nx_ip_packet_deferred_receive Defer IP packet receive */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* Driver */
75 /* */
76 /* RELEASE HISTORY */
77 /* */
78 /* DATE NAME DESCRIPTION */
79 /* */
80 /* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
81 /* */
82 /**************************************************************************/
_nx_udp_socket_driver_packet_receive(NX_UDP_SOCKET * socket_ptr,NX_PACKET * packet_ptr,NXD_ADDRESS * local_ip,NXD_ADDRESS * remote_ip,UINT remote_port)83 VOID _nx_udp_socket_driver_packet_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
84 NXD_ADDRESS *local_ip, NXD_ADDRESS *remote_ip, UINT remote_port)
85 {
86
87 NX_IP *ip_ptr;
88 NX_UDP_HEADER *udp_header_ptr;
89
90 /* Setup the IP pointer. */
91 ip_ptr = socket_ptr -> nx_udp_socket_ip_ptr;
92
93 if (packet_ptr == NX_NULL)
94 {
95
96 /* Socket error. Just ignore. */
97 return;
98 }
99
100 /* Fake UDP and IP header. */
101 /* Prepend the UDP header to the packet. First, make room for the UDP header. */
102 packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_UDP_HEADER);
103
104 /* Increase the packet length. */
105 packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_UDP_HEADER);
106
107 /* Setup the UDP header pointer. */
108 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
109 udp_header_ptr = (NX_UDP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
110
111 /* Build the first 32-bit word of the UDP header. */
112 udp_header_ptr -> nx_udp_header_word_0 =
113 ((ULONG)remote_port << NX_SHIFT_BY_16) | (ULONG)socket_ptr -> nx_udp_socket_port;
114
115 /* Build the second 32-bit word of the UDP header. */
116 udp_header_ptr -> nx_udp_header_word_1 = (packet_ptr -> nx_packet_length << NX_SHIFT_BY_16);
117
118 /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
119 swap the endian of the UDP header. */
120 NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0);
121 NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1);
122
123 #ifndef NX_DISABLE_IPV4
124 if (remote_ip -> nxd_ip_version == NX_IP_VERSION_V4)
125 {
126 _nx_ip_header_add(ip_ptr, packet_ptr, remote_ip -> nxd_ip_address.v4,
127 local_ip -> nxd_ip_address.v4,
128 socket_ptr -> nx_udp_socket_type_of_service,
129 socket_ptr -> nx_udp_socket_time_to_live,
130 NX_IP_UDP,
131 socket_ptr -> nx_udp_socket_fragment_enable);
132 }
133 #endif /* !NX_DISABLE_IPV4 */
134
135 #ifdef FEATURE_NX_IPV6
136 if (remote_ip -> nxd_ip_version == NX_IP_VERSION_V6)
137 {
138 if (_nx_ipv6_header_add(ip_ptr, &packet_ptr,
139 NX_PROTOCOL_UDP,
140 packet_ptr -> nx_packet_length,
141 ip_ptr -> nx_ipv6_hop_limit,
142 remote_ip -> nxd_ip_address.v6,
143 local_ip -> nxd_ip_address.v6,
144 NX_NULL))
145 {
146
147 /* Release the IP internal mutex. */
148 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
149 return;
150 }
151 }
152 #endif /* FEATURE_NX_IPV6 */
153
154 _nx_ip_packet_deferred_receive(ip_ptr, packet_ptr);
155 }
156 #endif /* NX_ENABLE_TCPIP_OFFLOAD */
157
158