1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Component */
17 /** */
18 /** User Datagram Protocol (UDP) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "nx_api.h"
29 #include "nx_ip.h"
30 #include "nx_udp.h"
31 #include "nx_packet.h"
32 #include "nx_ipv6.h"
33
34
35 /* Bring in externs for caller checking code. */
36
37 NX_CALLER_CHECKING_EXTERNS
38
39
40 /**************************************************************************/
41 /* */
42 /* FUNCTION RELEASE */
43 /* */
44 /* _nxde_udp_socket_send PORTABLE C */
45 /* 6.1 */
46 /* AUTHOR */
47 /* */
48 /* Yuxin Zhou, Microsoft Corporation */
49 /* */
50 /* DESCRIPTION */
51 /* */
52 /* This function checks for errors in the UDP socket send */
53 /* function call. */
54 /* */
55 /* INPUT */
56 /* */
57 /* socket_ptr Pointer to UDP socket */
58 /* packet_ptr Pointer to UDP packet */
59 /* ip_address IP address */
60 /* port 16-bit UDP port number */
61 /* */
62 /* OUTPUT */
63 /* */
64 /* status Completion status */
65 /* NX_PTR_ERROR Invalid pointer input or */
66 /* invalid packet input */
67 /* NX_NOT_ENABLED UDP not enabled on IP instance*/
68 /* NX_IP_ADDRESS_ERROR Invalid IP address input */
69 /* NX_INVALID_PORT Invalid UDP destination port */
70 /* NX_UNDERFLOW Check for invalid packet */
71 /* prepend pointer */
72 /* NX_OVERFLOW Check for invalid packet */
73 /* prepend pointer */
74 /* */
75 /* CALLS */
76 /* */
77 /* _nxd_udp_socket_send Actual UDP socket send */
78 /* function */
79 /* */
80 /* CALLED BY */
81 /* */
82 /* Application Code */
83 /* */
84 /* RELEASE HISTORY */
85 /* */
86 /* DATE NAME DESCRIPTION */
87 /* */
88 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
89 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
90 /* resulting in version 6.1 */
91 /* */
92 /**************************************************************************/
_nxde_udp_socket_send(NX_UDP_SOCKET * socket_ptr,NX_PACKET ** packet_ptr_ptr,NXD_ADDRESS * ip_address,UINT port)93 UINT _nxde_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr_ptr, NXD_ADDRESS *ip_address, UINT port)
94 {
95
96 NX_PACKET *packet_ptr;
97 UINT status;
98 UINT ip_header_size = 0;
99
100
101 /* Setup packet pointer. */
102 packet_ptr = *packet_ptr_ptr;
103
104 /* Check for invalid input pointers. */
105 if ((socket_ptr == NX_NULL) || (socket_ptr -> nx_udp_socket_id != NX_UDP_ID) || (ip_address == NX_NULL))
106 {
107 return(NX_PTR_ERROR);
108 }
109
110 /* Check for invalid packet pointers and packets not marked for allocation. */
111 /* Cast the ULONG into a packet pointer. Since this is exactly what we wish to do, disable the lint warning with the following comment: */
112 /*lint -e{923} suppress cast of ULONG to pointer. */
113 if ((packet_ptr == NX_NULL) ||
114 (packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next != ((NX_PACKET *)NX_PACKET_ALLOCATED)))
115 {
116
117 return(NX_PTR_ERROR);
118 }
119
120 /* Check if UDP is enabled. */
121 if (!(socket_ptr -> nx_udp_socket_ip_ptr) -> nx_ip_udp_packet_receive)
122 {
123 return(NX_NOT_ENABLED);
124 }
125
126
127 if ((ip_address -> nxd_ip_version != NX_IP_VERSION_V4) &&
128 (ip_address -> nxd_ip_version != NX_IP_VERSION_V6))
129 {
130 return(NX_IP_ADDRESS_ERROR);
131 }
132
133 #ifndef NX_DISABLE_IPV4
134 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
135 {
136 if (ip_address -> nxd_ip_address.v4 == 0)
137 {
138 return(NX_IP_ADDRESS_ERROR);
139 }
140
141 ip_header_size = (UINT)sizeof(NX_IPV4_HEADER);
142 }
143 #endif /* !NX_DISABLE_IPV4 */
144
145 #ifdef FEATURE_NX_IPV6
146 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
147 {
148 /* Check for invalid IP address. */
149 if (CHECK_UNSPECIFIED_ADDRESS(&ip_address -> nxd_ip_address.v6[0]))
150 {
151 return(NX_IP_ADDRESS_ERROR);
152 }
153
154 ip_header_size = (UINT)sizeof(NX_IPV6_HEADER);
155 }
156 #endif /* FEATURE_NX_IPV6 */
157
158 /* Check for an invalid port. */
159 if (((ULONG)port) > (ULONG)NX_MAX_PORT)
160 {
161 return(NX_INVALID_PORT);
162 }
163
164 /* Check for an invalid packet prepend pointer. */
165 /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
166 if ((INT)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < (INT)(ip_header_size + sizeof(NX_UDP_HEADER)))
167 {
168
169 #ifndef NX_DISABLE_UDP_INFO
170 /* Increment the total UDP invalid packet count. */
171 (socket_ptr -> nx_udp_socket_ip_ptr) -> nx_ip_udp_invalid_packets++;
172
173 /* Increment the total UDP invalid packet count for this socket. */
174 socket_ptr -> nx_udp_socket_invalid_packets++;
175 #endif
176
177 /* Return error code. */
178 return(NX_UNDERFLOW);
179 }
180
181 /* Check for an invalid packet append pointer. */
182 /*lint -e{946} suppress pointer subtraction, since it is necessary. */
183 if (packet_ptr -> nx_packet_append_ptr > packet_ptr -> nx_packet_data_end)
184 {
185
186 #ifndef NX_DISABLE_UDP_INFO
187 /* Increment the total UDP invalid packet count. */
188 (socket_ptr -> nx_udp_socket_ip_ptr) -> nx_ip_udp_invalid_packets++;
189
190 /* Increment the total UDP invalid packet count for this socket. */
191 socket_ptr -> nx_udp_socket_invalid_packets++;
192 #endif
193
194 /* Return error code. */
195 return(NX_OVERFLOW);
196 }
197
198 /* Check for appropriate caller. */
199 NX_THREADS_ONLY_CALLER_CHECKING
200
201 /* Call actual UDP socket send function. */
202 status = _nxd_udp_socket_send(socket_ptr, packet_ptr, ip_address, port);
203
204 /* Determine if the packet send was successful. */
205 if (status == NX_SUCCESS)
206 {
207
208 /* Yes, now clear the application's packet pointer so it can't be accidentally
209 used again by the application. This is only done when error checking is
210 enabled. */
211 *packet_ptr_ptr = NX_NULL;
212 }
213
214 /* Return completion status. */
215 return(status);
216 }
217
218