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 /** Internet Protocol (IP) */
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_packet.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _nx_packet_data_extract_offset PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Yuxin Zhou, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function copies data from a NetX packet (or packet chain) into */
45 /* the supplied user buffer. If an empty packet (no data) is */
46 /* received, zero bytes are copied, and the function returns without */
47 /* errors. */
48 /* */
49 /* Note that this function extracts data from a packet into user */
50 /* supplied buffer. It does not modify packet internal state */
51 /* information. The data being extracted is still available in the */
52 /* original packet for consumption again. */
53 /* */
54 /* INPUT */
55 /* */
56 /* packet_ptr Pointer to the source packet */
57 /* offset Offset from start of data */
58 /* buffer_start Pointer to destination data area */
59 /* buffer_length Size in bytes */
60 /* bytes_copied Number of bytes copied */
61 /* */
62 /* OUTPUT */
63 /* */
64 /* status Completion status */
65 /* */
66 /* CALLS */
67 /* */
68 /* None */
69 /* */
70 /* CALLED BY */
71 /* */
72 /* Application Code */
73 /* */
74 /* RELEASE HISTORY */
75 /* */
76 /* DATE NAME DESCRIPTION */
77 /* */
78 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
79 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
80 /* verified memcpy use cases, */
81 /* resulting in version 6.1 */
82 /* */
83 /**************************************************************************/
_nx_packet_data_extract_offset(NX_PACKET * packet_ptr,ULONG offset,VOID * buffer_start,ULONG buffer_length,ULONG * bytes_copied)84 UINT _nx_packet_data_extract_offset(NX_PACKET *packet_ptr, ULONG offset, VOID *buffer_start, ULONG buffer_length, ULONG *bytes_copied)
85 {
86
87 ULONG remaining_bytes;
88 UCHAR *source_ptr;
89 UCHAR *destination_ptr;
90 ULONG offset_bytes;
91 #ifndef NX_DISABLE_PACKET_CHAIN
92 ULONG packet_fragment_length;
93 #endif /* NX_DISABLE_PACKET_CHAIN */
94 ULONG bytes_to_copy;
95 NX_PACKET *working_packet_ptr;
96
97
98 working_packet_ptr = packet_ptr;
99
100 /* Check for an invalid offset or packet length. */
101 if (offset >= working_packet_ptr -> nx_packet_length)
102 {
103
104 /* Note: A zero offset with a packet of zero length is ok. */
105 if (offset == 0)
106 {
107
108 *bytes_copied = 0;
109 return(NX_SUCCESS);
110 }
111
112 /* Otherwise, this is an invalid offset or packet length. */
113 return(NX_PACKET_OFFSET_ERROR);
114 }
115
116
117 /* Initialize the source pointer to NULL. */
118 source_ptr = NX_NULL;
119
120 /* Traverse packet chain to offset. */
121 offset_bytes = offset;
122 #ifndef NX_DISABLE_PACKET_CHAIN
123 while (working_packet_ptr)
124 {
125
126 /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
127 packet_fragment_length = (ULONG)((working_packet_ptr -> nx_packet_append_ptr - working_packet_ptr -> nx_packet_prepend_ptr));
128
129 /* Determine if we are at the offset location fragment in the packet chain */
130 if (packet_fragment_length > offset_bytes)
131 {
132
133 /* Setup loop to copy from this packet. */
134 source_ptr = working_packet_ptr -> nx_packet_prepend_ptr + offset_bytes;
135
136 /* Yes, get out of this loop. */
137 break;
138 }
139
140
141 /* Decrement the remaining offset bytes*/
142 offset_bytes = offset_bytes - packet_fragment_length;
143
144 /* Move to next packet. */
145 working_packet_ptr = working_packet_ptr -> nx_packet_next;
146 }
147 #else /* NX_DISABLE_PACKET_CHAIN */
148 /* Setup loop to copy from this packet. */
149 source_ptr = working_packet_ptr -> nx_packet_prepend_ptr + offset_bytes;
150
151 #endif /* NX_DISABLE_PACKET_CHAIN */
152
153 /* Check for a valid source pointer. */
154 if (source_ptr == NX_NULL)
155 {
156 return(NX_PACKET_OFFSET_ERROR);
157 }
158
159 /* Setup the destination pointer. */
160 destination_ptr = buffer_start;
161 bytes_to_copy = (packet_ptr -> nx_packet_length - offset);
162
163 /* Pickup the amount of bytes to copy. */
164 if (bytes_to_copy < buffer_length)
165 {
166 *bytes_copied = bytes_to_copy; /* the amount of bytes returned to the caller */
167 remaining_bytes = bytes_to_copy; /* for use in the copy loop */
168 }
169 else
170 {
171 *bytes_copied = buffer_length;
172 remaining_bytes = buffer_length;
173 }
174
175 #ifndef NX_DISABLE_PACKET_CHAIN
176 /* Loop to copy bytes from packet(s). */
177 while (working_packet_ptr && remaining_bytes)
178 {
179 #endif /* NX_DISABLE_PACKET_CHAIN */
180
181 /* Calculate bytes to copy. */
182 /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
183 bytes_to_copy = (ULONG)(working_packet_ptr -> nx_packet_append_ptr - source_ptr);
184 if (remaining_bytes < bytes_to_copy)
185 {
186 bytes_to_copy = remaining_bytes;
187 }
188
189 /* Copy data from this packet. */
190 memcpy(destination_ptr, source_ptr, bytes_to_copy); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
191
192 /* Update the pointers. */
193 destination_ptr += bytes_to_copy;
194 remaining_bytes -= bytes_to_copy;
195
196 #ifndef NX_DISABLE_PACKET_CHAIN
197 /* Move to next packet. */
198 working_packet_ptr = working_packet_ptr -> nx_packet_next;
199
200 /* Check for a next packet. */
201 if (working_packet_ptr)
202 {
203
204 /* Setup new source pointer. */
205 source_ptr = working_packet_ptr -> nx_packet_prepend_ptr;
206 }
207 }
208 #endif /* NX_DISABLE_PACKET_CHAIN */
209
210 /* If trace is enabled, insert this event into the trace buffer. */
211 NX_TRACE_IN_LINE_INSERT(NX_TRACE_PACKET_DATA_EXTRACT_OFFSET, packet_ptr, buffer_length, *bytes_copied, 0, NX_TRACE_PACKET_EVENTS, 0, 0);
212
213 /* Return successful completion. */
214 return(NX_SUCCESS);
215 }
216
217