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_ipv4.h"
30 #ifdef FEATURE_NX_IPV6
31 #include "nx_ipv6.h"
32 #endif
33 
34 
35 /**************************************************************************/
36 /*                                                                        */
37 /*  FUNCTION                                               RELEASE        */
38 /*                                                                        */
39 /*    _nxd_udp_packet_info_extract                        PORTABLE C      */
40 /*                                                           6.1          */
41 /*  AUTHOR                                                                */
42 /*                                                                        */
43 /*    Yuxin Zhou, Microsoft Corporation                                   */
44 /*                                                                        */
45 /*  DESCRIPTION                                                           */
46 /*                                                                        */
47 /*    This function extracts the source IP address, protocol, (the        */
48 /*    protocol is always UDP), port number and the incoming interface     */
49 /*    from the incoming packet.                                           */
50 /*                                                                        */
51 /*  INPUT                                                                 */
52 /*                                                                        */
53 /*    packet_ptr                            Pointer to UDP packet         */
54 /*    ip_address                            Pointer to sender IP address  */
55 /*    protocol                              Pointer to packet protocol.   */
56 /*                                            Always 17 (UDP)             */
57 /*    port                                  Pointer to sender source port */
58 /*    interface_index                         Pointer to interface index  */
59 /*                                            packet received on          */
60 /*                                                                        */
61 /*  OUTPUT                                                                */
62 /*                                                                        */
63 /*    status                                Completion status             */
64 /*                                                                        */
65 /*  CALLS                                                                 */
66 /*                                                                        */
67 /*    None                                                                */
68 /*                                                                        */
69 /*  CALLED BY                                                             */
70 /*                                                                        */
71 /*    Application Code                                                    */
72 /*                                                                        */
73 /*  RELEASE HISTORY                                                       */
74 /*                                                                        */
75 /*    DATE              NAME                      DESCRIPTION             */
76 /*                                                                        */
77 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
78 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
79 /*                                            resulting in version 6.1    */
80 /*                                                                        */
81 /**************************************************************************/
_nxd_udp_packet_info_extract(NX_PACKET * packet_ptr,NXD_ADDRESS * ip_address,UINT * protocol,UINT * port,UINT * interface_index)82 UINT  _nxd_udp_packet_info_extract(NX_PACKET *packet_ptr, NXD_ADDRESS *ip_address,
83                                    UINT *protocol, UINT *port, UINT *interface_index)
84 {
85 
86 ULONG          *temp_ptr;
87 UINT            source_port;
88 NX_INTERFACE   *nx_interface;
89 #ifndef NX_DISABLE_IPV4
90 NX_IPV4_HEADER *ipv4_header;
91 #endif /* !NX_DISABLE_IPV4  */
92 #ifdef TX_ENABLE_EVENT_TRACE
93 ULONG           address = 0;
94 #endif  /* TX_ENABLE_EVENT_TRACE */
95 #ifdef FEATURE_NX_IPV6
96 NX_IPV6_HEADER *ipv6_header;
97 #endif /* FEATURE_NX_IPV6 */
98 
99 
100     if (ip_address)
101     {
102 
103 #ifndef NX_DISABLE_IPV4
104         if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4)
105         {
106 
107             /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
108             ipv4_header = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_ip_header;
109 
110             ip_address -> nxd_ip_version = NX_IP_VERSION_V4;
111 
112             /* At this point, the IP address in the IPv4 header is in host byte order. */
113             ip_address -> nxd_ip_address.v4 = ipv4_header -> nx_ip_header_source_ip;
114 
115 #ifdef TX_ENABLE_EVENT_TRACE
116             address = ip_address -> nxd_ip_address.v4;
117 #endif  /* TX_ENABLE_EVENT_TRACE */
118         }
119         else
120 #endif /* !NX_DISABLE_IPV4  */
121 
122 #ifdef FEATURE_NX_IPV6
123         if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6)
124         {
125 
126             /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
127             ipv6_header = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header;
128 
129             ip_address -> nxd_ip_version = NX_IP_VERSION_V6;
130 
131             /* At this point, the IP address in the IPv6 header is in host byte order. */
132             COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_source_ip, ip_address -> nxd_ip_address.v6);
133 
134 #ifdef TX_ENABLE_EVENT_TRACE
135             address = ip_address -> nxd_ip_address.v6[3];
136 #endif /* TX_ENABLE_EVENT_TRACE*/
137         }
138         else
139 #endif /* FEATURE_NX_IPV6 */
140         {
141 
142             /* Invalid IP version . */
143             return(NX_INVALID_PACKET);
144         }
145     }
146 
147     /* Build an address to the current top of the packet.  */
148     /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
149     temp_ptr =  (ULONG *)packet_ptr -> nx_packet_prepend_ptr;
150 
151     /* Pickup the source port.  */
152     source_port =  (UINT)(*(temp_ptr - 2) >> NX_SHIFT_BY_16);
153     if (port != NX_NULL)
154     {
155         *port = source_port;
156     }
157 
158     if (protocol != NX_NULL)
159     {
160         *protocol = 0x11;
161     }
162 
163     /* If trace is enabled, insert this event into the trace buffer.  */
164     NX_TRACE_IN_LINE_INSERT(NX_TRACE_UDP_SOURCE_EXTRACT, packet_ptr, address, source_port, 0, NX_TRACE_PACKET_EVENTS, 0, 0);
165 
166     if (interface_index == NX_NULL)
167     {
168         return(NX_SUCCESS);
169     }
170 
171     /* Search for interface index number.  Initialize interface value as
172        invalid (0xFFFFFFFF).  Once we find valid interface, we will update
173        the returned value. */
174     *interface_index = 0xFFFFFFFF;
175 
176     if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4)
177     {
178         nx_interface = packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
179     }
180 #ifdef FEATURE_NX_IPV6
181     else if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6)
182     {
183         if (packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr == NX_NULL)
184         {
185 
186             /* No interface attached.  Done here, and return success. */
187             return(NX_SUCCESS);
188         }
189         else
190         {
191             nx_interface = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;
192         }
193     }
194 #endif /* FEATURE_NX_IPV6 */
195     else
196     {
197         return(NX_SUCCESS);
198     }
199 
200     if (nx_interface == NX_NULL)
201     {
202 
203         /* No interface attached.  Done here, and return success. */
204         return(NX_SUCCESS);
205     }
206 
207     *interface_index = (UINT)nx_interface -> nx_interface_index;
208 
209     return(NX_SUCCESS);
210 }
211 
212