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