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 /**   Packet Pool Management (Packet)                                     */
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_adjust                              PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Yuxin Zhou, Microsoft Corporation                                   */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function adjusts the packet data to fill the specified header. */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    packet_ptr                            Pointer to the source packet  */
49 /*    header_size                           The size of header            */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    status                                Completion status             */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    _nx_packet_allocate                   Allocate data packet          */
58 /*    _nx_packet_data_append                Packet data append service    */
59 /*    _nx_packet_release                    Release data packet           */
60 /*                                                                        */
61 /*  CALLED BY                                                             */
62 /*                                                                        */
63 /*    _nx_ip_forward_packet_process         Forward IP packet             */
64 /*                                                                        */
65 /*  RELEASE HISTORY                                                       */
66 /*                                                                        */
67 /*    DATE              NAME                      DESCRIPTION             */
68 /*                                                                        */
69 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
70 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
71 /*                                            verified memcpy use cases,  */
72 /*                                            verified memmove use cases, */
73 /*                                            resulting in version 6.1    */
74 /*                                                                        */
75 /**************************************************************************/
_nx_packet_data_adjust(NX_PACKET * packet_ptr,ULONG header_size)76 UINT  _nx_packet_data_adjust(NX_PACKET *packet_ptr, ULONG header_size)
77 {
78 
79 ULONG           available_size;
80 ULONG           shift_size;
81 #ifndef NX_DISABLE_PACKET_CHAIN
82 UINT            status;
83 ULONG           append_size;
84 UCHAR          *data_start;
85 NX_PACKET      *work_ptr;
86 #endif /* !NX_DISABLE_PACKET_CHAIN  */
87 
88 
89     /* Add debug information. */
90     NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
91 
92     /* The header must be filled in one packet. */
93     if (((ALIGN_TYPE)packet_ptr -> nx_packet_data_end - (ALIGN_TYPE)packet_ptr -> nx_packet_data_start) < header_size)
94     {
95         return(NX_UNDERFLOW);
96     }
97 
98     /* 1. Check if there is enough space to add header.  */
99     if (((ALIGN_TYPE)packet_ptr -> nx_packet_prepend_ptr - (ALIGN_TYPE)packet_ptr -> nx_packet_data_start) >= header_size)
100     {
101 
102         /* Yes. Just return success. */
103         return(NX_SUCCESS);
104     }
105 
106     /* Compute the total avilable size in this packet.  */
107     available_size = (ULONG)(((ALIGN_TYPE)packet_ptr -> nx_packet_prepend_ptr - (ALIGN_TYPE)packet_ptr -> nx_packet_data_start) +
108                              ((ALIGN_TYPE)packet_ptr -> nx_packet_data_end - (ALIGN_TYPE)packet_ptr -> nx_packet_append_ptr));
109 
110     /* 2. Would the header fit into the available space?  */
111     if (available_size >= header_size)
112     {
113 
114         /* Yes, adjust the data.  */
115 
116         /* Calculate the shift data size. */
117         shift_size = (ULONG)((ALIGN_TYPE)packet_ptr -> nx_packet_append_ptr - (ALIGN_TYPE)packet_ptr -> nx_packet_prepend_ptr);
118 
119         /* Move the data, */
120         memmove(packet_ptr -> nx_packet_data_start + header_size, packet_ptr -> nx_packet_prepend_ptr, shift_size); /* Use case of memmove is verified.  */
121 
122         /* Update the prepend and append pointer.  */
123         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_data_start + header_size;
124         packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + shift_size;
125     }
126     else
127     {
128 
129 #ifndef NX_DISABLE_PACKET_CHAIN
130 
131         /* 3. Current packet does not have enough space to fill the header.
132               Allocate a new packet to fill the overflowing data and chain the packet.  */
133 
134         /* Odd value of header_size is not supported now.
135          * In _nx_ip_checksum_compute(), nx_packet_append_ptr must not be odd value. */
136         if (header_size & 1)
137         {
138             return(NX_NOT_SUPPORTED);
139         }
140 
141         /* Calculate the append data size. */
142         append_size = header_size - available_size;
143 
144         /* Set the append data pointer.  */
145         data_start = packet_ptr -> nx_packet_append_ptr - append_size;
146 
147         /* Allocate a packet.  */
148         status = _nx_packet_allocate(packet_ptr -> nx_packet_pool_owner, &work_ptr, 0, NX_NO_WAIT);
149 
150         /* Check status.  */
151         if (status)
152         {
153             return(status);
154         }
155 
156         /* Firstly, append the overflowing data to the new packet.. */
157         memcpy(work_ptr -> nx_packet_prepend_ptr, data_start, append_size); /* Use case of memcpy is verified.  lgtm[cpp/banned-api-usage-required-any] */
158         work_ptr -> nx_packet_append_ptr = (UCHAR *)((ALIGN_TYPE)work_ptr -> nx_packet_prepend_ptr + append_size);
159 
160         /* Secondly, calculate the shift data size.  */
161         shift_size = (ULONG)(((ALIGN_TYPE)packet_ptr -> nx_packet_append_ptr - (ALIGN_TYPE)packet_ptr -> nx_packet_prepend_ptr) - append_size);
162 
163         /* Move the data.  */
164         memmove(packet_ptr -> nx_packet_data_start + header_size, packet_ptr -> nx_packet_prepend_ptr, shift_size); /* Use case of memmove is verified.  */
165 
166         /* Update the prepend and append pointer.  */
167         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_data_start + header_size;
168         packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + shift_size;
169 
170         /* At this point, all the necessary packets have been allocated.
171            We need to link this new packet to the next of the supplied packet.  */
172         work_ptr -> nx_packet_next = packet_ptr -> nx_packet_next;
173         packet_ptr -> nx_packet_next = work_ptr;
174 
175         /* Update the last packet pointer.  */
176         if (packet_ptr -> nx_packet_last == NX_NULL)
177         {
178             packet_ptr -> nx_packet_last = work_ptr;
179         }
180 #else /* NX_DISABLE_PACKET_CHAIN  */
181 
182         /* Return error code.  */
183         return(NX_UNDERFLOW);
184 #endif /* !NX_DISABLE_PACKET_CHAIN  */
185     }
186 
187     /* Return successful completion.  */
188     return(NX_SUCCESS);
189 }
190 
191