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 "nx_udp.h"
29 #include "nx_ip.h"
30 #include "nx_ipv6.h"
31
32 /* Bring in externs for caller checking code. */
33
34 NX_CALLER_CHECKING_EXTERNS
35
36
37 /**************************************************************************/
38 /* */
39 /* FUNCTION RELEASE */
40 /* */
41 /* _nxde_udp_socket_source_send PORTABLE C */
42 /* 6.1 */
43 /* AUTHOR */
44 /* */
45 /* Yuxin Zhou, Microsoft Corporation */
46 /* */
47 /* DESCRIPTION */
48 /* */
49 /* This function performs error checking on the UDP socket send */
50 /* via source address service. */
51 /* */
52 /* INPUT */
53 /* */
54 /* socket_ptr Pointer to the UDP socket */
55 /* packet_ptr Pointer to packet to send */
56 /* ip_address Pointer to destination address*/
57 /* port Destination port number */
58 /* address_index Index of IPv4 or IPv6 address */
59 /* to use as the source address*/
60 /* */
61 /* OUTPUT */
62 /* */
63 /* status Actual completion status */
64 /* NX_PTR_ERROR Invalid pointer input */
65 /* NX_NOT_ENABLED UDP not enabled on IP instance*/
66 /* NX_IP_ADDRESS_ERROR Invalid input address */
67 /* NX_INVALID_INTERFACE Invalid interface input */
68 /* */
69 /* CALLS */
70 /* */
71 /* _nxde_udp_socket_source_send Actual UDP socket socket */
72 /* send function */
73 /* */
74 /* CALLED BY */
75 /* */
76 /* Application Code */
77 /* */
78 /* RELEASE HISTORY */
79 /* */
80 /* DATE NAME DESCRIPTION */
81 /* */
82 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
83 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
84 /* resulting in version 6.1 */
85 /* */
86 /**************************************************************************/
87
_nxde_udp_socket_source_send(NX_UDP_SOCKET * socket_ptr,NX_PACKET * packet_ptr,NXD_ADDRESS * ip_address,UINT port,UINT address_index)88 UINT _nxde_udp_socket_source_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
89 NXD_ADDRESS *ip_address, UINT port, UINT address_index)
90 {
91
92 UINT status;
93 UINT ip_header_size;
94
95
96 /* Check for invalid input pointers. */
97 if ((socket_ptr == NX_NULL) || (packet_ptr == NX_NULL) || (ip_address == NX_NULL) || (socket_ptr -> nx_udp_socket_id != NX_UDP_ID))
98 {
99 return(NX_PTR_ERROR);
100 }
101
102 /* Verify UDP is enabled. */
103 if (!(socket_ptr -> nx_udp_socket_ip_ptr) -> nx_ip_udp_packet_receive)
104 {
105 return(NX_NOT_ENABLED);
106 }
107
108 /* Check that the destination address version is either IPv4 or IPv6. */
109 #ifndef NX_DISABLE_IPV4
110 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
111 {
112 if (address_index >= NX_MAX_IP_INTERFACES)
113 {
114 return(NX_INVALID_INTERFACE);
115 }
116
117 if (ip_address -> nxd_ip_address.v4 == 0)
118 {
119 return(NX_IP_ADDRESS_ERROR);
120 }
121
122 ip_header_size = (UINT)sizeof(NX_IPV4_HEADER);
123 }
124 else
125 #endif /* !NX_DISABLE_IPV4 */
126
127 #ifdef FEATURE_NX_IPV6
128 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
129 {
130 if (address_index >= (NX_MAX_IPV6_ADDRESSES + NX_LOOPBACK_IPV6_ENABLED))
131 {
132 return(NX_INVALID_INTERFACE);
133 }
134
135 if (CHECK_UNSPECIFIED_ADDRESS(&ip_address -> nxd_ip_address.v6[0]))
136 {
137 return(NX_IP_ADDRESS_ERROR);
138 }
139
140 ip_header_size = (UINT)sizeof(NX_IPV6_HEADER);
141 }
142 else
143 #endif /* FEATURE_NX_IPV6 */
144 {
145 return(NX_IP_ADDRESS_ERROR);
146 }
147
148 /* Check for an invalid packet prepend pointer. */
149 /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
150 if ((INT)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < (INT)(ip_header_size + sizeof(NX_UDP_HEADER)))
151 {
152
153 #ifndef NX_DISABLE_UDP_INFO
154 /* Increment the total UDP invalid packet count. */
155 (socket_ptr -> nx_udp_socket_ip_ptr) -> nx_ip_udp_invalid_packets++;
156
157 /* Increment the total UDP invalid packet count for this socket. */
158 socket_ptr -> nx_udp_socket_invalid_packets++;
159 #endif
160
161 /* Return error code. */
162 return(NX_UNDERFLOW);
163 }
164
165 /* Check for an invalid packet append pointer. */
166 /*lint -e{946} suppress pointer subtraction, since it is necessary. */
167 if (packet_ptr -> nx_packet_append_ptr > packet_ptr -> nx_packet_data_end)
168 {
169
170 #ifndef NX_DISABLE_UDP_INFO
171 /* Increment the total UDP invalid packet count. */
172 (socket_ptr -> nx_udp_socket_ip_ptr) -> nx_ip_udp_invalid_packets++;
173
174 /* Increment the total UDP invalid packet count for this socket. */
175 socket_ptr -> nx_udp_socket_invalid_packets++;
176 #endif
177
178 /* Return error code. */
179 return(NX_OVERFLOW);
180 }
181
182 /* Check for an invalid port. */
183 if (((ULONG)port) > (ULONG)NX_MAX_PORT)
184 {
185 return(NX_INVALID_PORT);
186 }
187
188 /* Check for appropriate caller. */
189 NX_THREADS_ONLY_CALLER_CHECKING
190
191 /* Call actual UDP socket send function. */
192 status = _nxd_udp_socket_source_send(socket_ptr, packet_ptr, ip_address, port, address_index);
193
194 /* Return completion status. */
195 return(status);
196 }
197
198