|
65 | 65 | * vApplicationPingReplyHook() is called with the results. |
66 | 66 | */ |
67 | 67 | #if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) |
68 | | - static void prvProcessICMPEchoReply( ICMPPacket_t * const pxICMPPacket ); |
| 68 | + static void prvProcessICMPEchoReply( const NetworkBufferDescriptor_t * const pxNetworkBuffer ); |
69 | 69 | #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ |
70 | 70 |
|
71 | 71 | #if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) |
|
110 | 110 | case ipICMP_ECHO_REPLY: |
111 | 111 | #if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) |
112 | 112 | { |
113 | | - prvProcessICMPEchoReply( pxICMPPacket ); |
| 113 | + prvProcessICMPEchoReply( pxNetworkBuffer ); |
114 | 114 | } |
115 | 115 | #endif /* ipconfigSUPPORT_OUTGOING_PINGS */ |
116 | 116 | break; |
|
201 | 201 | /** |
202 | 202 | * @brief Process an ICMP echo reply. |
203 | 203 | * |
204 | | - * @param[in] pxICMPPacket The IP packet that contains the ICMP message. |
| 204 | + * @param[in] pxNetworkBuffer The network buffer descriptor containing the ICMP packet. |
205 | 205 | */ |
206 | | - static void prvProcessICMPEchoReply( ICMPPacket_t * const pxICMPPacket ) |
| 206 | + static void prvProcessICMPEchoReply( const NetworkBufferDescriptor_t * const pxNetworkBuffer ) |
207 | 207 | { |
| 208 | + /* The packet contained an ICMPv4 frame. */ |
| 209 | + /* MISRA Ref 11.3.1 [Misaligned access] */ |
| 210 | + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ |
| 211 | + /* coverity[misra_c_2012_rule_11_3_violation] */ |
| 212 | + ICMPPacket_t * pxICMPPacket = ( ICMPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; |
208 | 213 | ePingReplyStatus_t eStatus = eSuccess; |
209 | | - uint16_t usDataLength, usCount; |
| 214 | + uint16_t usDataLength, usByteCount, usCount; |
| 215 | + size_t usByteAvail; |
210 | 216 | uint8_t * pucByte; |
211 | 217 |
|
212 | 218 | /* Find the total length of the IP packet. */ |
213 | 219 | usDataLength = pxICMPPacket->xIPHeader.usLength; |
214 | | - usDataLength = FreeRTOS_ntohs( usDataLength ); |
| 220 | + usByteCount = FreeRTOS_ntohs( usDataLength ); |
| 221 | + usByteAvail = pxNetworkBuffer->xDataLength; |
215 | 222 |
|
216 | | - /* Remove the length of the IP headers to obtain the length of the ICMP |
217 | | - * message itself. */ |
218 | | - usDataLength = ( uint16_t ) ( ( ( uint32_t ) usDataLength ) - ipSIZE_OF_IPv4_HEADER ); |
| 223 | + if( usByteAvail >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_ICMPv4_HEADER ) ) |
| 224 | + { |
| 225 | + usByteAvail = usByteAvail - ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_ICMPv4_HEADER ); |
219 | 226 |
|
220 | | - /* Remove the length of the ICMP header, to obtain the length of |
221 | | - * data contained in the ping. */ |
222 | | - usDataLength = ( uint16_t ) ( ( ( uint32_t ) usDataLength ) - ipSIZE_OF_ICMPv4_HEADER ); |
| 227 | + if( usByteCount >= ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_ICMPv4_HEADER ) ) |
| 228 | + { |
| 229 | + usByteCount = ( uint16_t ) ( usByteCount - ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_ICMPv4_HEADER ) ); |
223 | 230 |
|
224 | | - /* Checksum has already been checked before in prvProcessIPPacket */ |
| 231 | + if( usByteCount <= usByteAvail ) |
| 232 | + { |
| 233 | + /* Checksum has already been checked before in prvProcessIPPacket */ |
225 | 234 |
|
226 | | - /* Find the first byte of the data within the ICMP packet. */ |
227 | | - pucByte = ( uint8_t * ) pxICMPPacket; |
228 | | - pucByte = &( pucByte[ sizeof( ICMPPacket_t ) ] ); |
| 235 | + /* Find the first byte of the data within the ICMP packet. */ |
| 236 | + pucByte = ( uint8_t * ) pxICMPPacket; |
| 237 | + /* Add an offset of 14 + 20 + 8. */ |
| 238 | + pucByte = &( pucByte[ sizeof( ICMPPacket_t ) ] ); |
229 | 239 |
|
230 | | - /* Check each byte. */ |
231 | | - for( usCount = 0; usCount < usDataLength; usCount++ ) |
232 | | - { |
233 | | - if( *pucByte != ( uint8_t ) ipECHO_DATA_FILL_BYTE ) |
| 240 | + /* Check each byte. */ |
| 241 | + for( usCount = 0; usCount < usByteCount; usCount++ ) |
| 242 | + { |
| 243 | + if( *pucByte != ( uint8_t ) ipECHO_DATA_FILL_BYTE ) |
| 244 | + { |
| 245 | + eStatus = eInvalidData; |
| 246 | + break; |
| 247 | + } |
| 248 | + |
| 249 | + pucByte++; |
| 250 | + } |
| 251 | + |
| 252 | + /* Call back into the application to pass it the result. */ |
| 253 | + vApplicationPingReplyHook( eStatus, pxICMPPacket->xICMPHeader.usIdentifier ); |
| 254 | + } |
| 255 | + } |
| 256 | + else |
234 | 257 | { |
235 | | - eStatus = eInvalidData; |
236 | | - break; |
| 258 | + /* usByteCount too small, drop. */ |
237 | 259 | } |
238 | | - |
239 | | - pucByte++; |
240 | 260 | } |
241 | | - |
242 | | - /* Call back into the application to pass it the result. */ |
243 | | - vApplicationPingReplyHook( eStatus, pxICMPPacket->xICMPHeader.usIdentifier ); |
| 261 | + else |
| 262 | + { |
| 263 | + /* Buffer too small, drop. */ |
| 264 | + } |
244 | 265 | } |
245 | 266 |
|
246 | 267 | #endif /* if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */ |
|
0 commit comments