mirror of
https://github.com/FreeRTOS/FreeRTOS-Plus-TCP
synced 2025-10-23 10:07:43 +08:00

* Check IPv6 packet length. * Fix unused compile warnings. * Move xCheckSizeFields to static function and fix unit test cases. * Add minimum length check for IPv6 transport layer.
280 lines
11 KiB
C
280 lines
11 KiB
C
/*
|
|
* FreeRTOS+TCP <DEVELOPMENT BRANCH>
|
|
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* https://www.FreeRTOS.org
|
|
* https://github.com/FreeRTOS
|
|
*/
|
|
|
|
#ifndef FREERTOS_IPV6_PRIVATE_H
|
|
#define FREERTOS_IPV6_PRIVATE_H
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
/* *INDENT-ON* */
|
|
|
|
/* Application level configuration options. */
|
|
#include "FreeRTOSIPConfig.h"
|
|
#include "FreeRTOSIPConfigDefaults.h"
|
|
#include "FreeRTOS_IP_Common.h"
|
|
#include "FreeRTOS_Sockets.h"
|
|
#include "IPTraceMacroDefaults.h"
|
|
#include "FreeRTOS_Stream_Buffer.h"
|
|
#if ( ipconfigUSE_TCP == 1 )
|
|
#include "FreeRTOS_TCP_WIN.h"
|
|
#include "FreeRTOS_TCP_IP.h"
|
|
#endif
|
|
|
|
#include "semphr.h"
|
|
|
|
#include "event_groups.h"
|
|
|
|
/* MISRA Ref 20.5.1 [Use of undef] */
|
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-2051 */
|
|
/* coverity[misra_c_2012_rule_20_5_violation] */
|
|
#undef TCP_PACKET_SIZE
|
|
#define TCP_PACKET_SIZE ( sizeof( TCPPacket_IPv6_t ) )
|
|
|
|
/* The offset from the UDP payload where the IP type will be stored.
|
|
* For IPv4 packets, this it located 6 bytes before pucEthernetBuffer.
|
|
* For IPv6 packets, this it located in the usual 'ucVersionTrafficClass'. */
|
|
#define ipIP_TYPE_OFFSET ( 6U )
|
|
/* The offset into an IP packet into which the IP data (payload) starts. */
|
|
#define ipIPv6_PAYLOAD_OFFSET ( sizeof( IPPacket_IPv6_t ) )
|
|
/* MISRA Ref 20.5.1 [Use of undef] */
|
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-2051 */
|
|
/* coverity[misra_c_2012_rule_20_5_violation] */
|
|
/* The maximum UDP payload length. */
|
|
#undef ipMAX_UDP_PAYLOAD_LENGTH
|
|
#define ipMAX_UDP_PAYLOAD_LENGTH ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv6_HEADER ) - ipSIZE_OF_UDP_HEADER )
|
|
/* The offset into a UDP packet at which the UDP data (payload) starts. */
|
|
#define ipUDP_PAYLOAD_OFFSET_IPv6 ( sizeof( UDPPacket_IPv6_t ) )
|
|
/* The value of 'ipUDP_PAYLOAD_IP_TYPE_OFFSET' is 42 + 6 = 48 bytes. */
|
|
#define ipUDP_PAYLOAD_IPv6_TYPE_OFFSET ( sizeof( UDPPacket_IPv6_t ) + ipIP_TYPE_OFFSET )
|
|
|
|
#if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
|
|
|
#define ipIPv6_FRAME_TYPE ( 0xDD86U ) /* Ethernet frame types. */
|
|
|
|
#else /* if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) */
|
|
|
|
#define ipIPv6_FRAME_TYPE ( 0x86DDU ) /* Ethernet frame types. */
|
|
|
|
#endif /* ipconfigBYTE_ORDER */
|
|
|
|
/* In this library, there is often a cast from a character pointer
|
|
* to a pointer to a struct.
|
|
* In order to suppress MISRA warnings, do the cast within a macro,
|
|
* which can be exempt from warnings:
|
|
*
|
|
* 3 required by MISRA:
|
|
* -emacro(740,ipPOINTER_CAST) // 750: Unusual pointer cast (incompatible indirect types) [MISRA 2012 Rule 1.3, required])
|
|
* -emacro(9005,ipPOINTER_CAST) // 9005: attempt to cast away const/volatile from a pointer or reference [MISRA 2012 Rule 11.8, required]
|
|
* -emacro(9087,ipPOINTER_CAST) // 9087: cast performed between a pointer to object type and a pointer to a different object type [MISRA 2012 Rule 11.3, required]
|
|
*
|
|
* 2 advisory by MISRA:
|
|
* -emacro(9079,ipPOINTER_CAST) // 9079: conversion from pointer to void to pointer to other type [MISRA 2012 Rule 11.5, advisory])
|
|
* --emacro((826),ipPOINTER_CAST) // 826: Suspicious pointer-to-pointer conversion (area too small)
|
|
*
|
|
* The MISRA warnings can safely be suppressed because all casts are planned with care.
|
|
*/
|
|
|
|
#define ipPOINTER_CAST( TYPE, pointer ) ( ( TYPE ) ( pointer ) )
|
|
|
|
/* Sequence and ACK numbers are essentially unsigned (uint32_t). But when
|
|
* a distance is calculated, it is useful to use signed numbers:
|
|
* int32_t lDistance = ( int32_t ) ( ulSeq1 - ulSeq2 );
|
|
*
|
|
* 1 required by MISRA:
|
|
* -emacro(9033,ipNUMERIC_CAST) // 9033: Impermissible cast of composite expression (different essential type categories) [MISRA 2012 Rule 10.8, required])
|
|
*
|
|
* 1 advisory by MISRA:
|
|
* -emacro(9030,ipNUMERIC_CAST) // 9030: Impermissible cast; cannot cast from 'essentially Boolean' to 'essentially signed' [MISRA 2012 Rule 10.5, advisory])
|
|
*/
|
|
|
|
#define ipNUMERIC_CAST( TYPE, expression ) ( ( TYPE ) ( expression ) )
|
|
|
|
|
|
/** @brief The macros vSetField16() and vSetField32() will write either a short or a 32-bit
|
|
* value into an array of bytes. They will be stored big-endian.
|
|
* The helper functions do the actual work.
|
|
*/
|
|
|
|
/*extern void vSetField16helper( uint8_t * pucBase,
|
|
* size_t uxOffset,
|
|
* uint16_t usValue );
|
|
#define vSetField16( pucBase, xType, xField, usValue ) \
|
|
* vSetField16helper( pucBase, offsetof( xType, xField ), usValue )
|
|
*
|
|
* extern void vSetField32helper( uint8_t * pucBase,
|
|
* size_t uxOffset,
|
|
* uint32_t ulValue );
|
|
#define vSetField32( pucBase, xType, xField, ulValue ) \
|
|
* vSetField32helper( pucBase, offsetof( xType, xField ), ulValue )
|
|
*/
|
|
|
|
/* As FreeRTOS_Routing is included later, use forward declarations
|
|
* of the two structs. */
|
|
struct xNetworkEndPoint;
|
|
struct xNetworkInterface;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xIP_HEADER_IPv6
|
|
{
|
|
uint8_t ucVersionTrafficClass; /**< The version field. 0 + 1 = 1 */
|
|
uint8_t ucTrafficClassFlow; /**< Traffic class and flow. 1 + 1 = 2 */
|
|
uint16_t usFlowLabel; /**< Flow label. 2 + 2 = 4 */
|
|
uint16_t usPayloadLength; /**< Number of bytes after the IPv6 header. 4 + 2 = 6 */
|
|
uint8_t ucNextHeader; /**< Next header: TCP, UDP, or ICMP. 6 + 1 = 7 */
|
|
uint8_t ucHopLimit; /**< Replaces the time to live from IPv4. 7 + 1 = 8 */
|
|
IPv6_Address_t xSourceAddress; /**< The IPv6 address of the sender. 8 + 16 = 24 */
|
|
IPv6_Address_t xDestinationAddress; /**< The IPv6 address of the receiver. 24 + 16 = 40 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xIP_HEADER_IPv6 IPHeader_IPv6_t;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xIP_EXT_HEADER_IPv6
|
|
{
|
|
uint8_t ucNextHeader; /**< Next header: TCP, UDP, or ICMP. 0 + 1 = 1 */
|
|
uint8_t ucHeaderExtLength; /**< Length of this header in 8-octet units, not including the first 8 octets. 1 + 1 = 2 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xIP_EXT_HEADER_IPv6 IPExtHeader_IPv6_t;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xICMPEcho_IPv6
|
|
{
|
|
uint8_t ucTypeOfMessage; /**< The message type. 0 + 1 = 1 */
|
|
uint8_t ucTypeOfService; /**< Type of service. 1 + 1 = 2 */
|
|
uint16_t usChecksum; /**< Checksum. 2 + 2 = 4 */
|
|
uint16_t usIdentifier; /**< Identifier. 4 + 2 = 6 */
|
|
uint16_t usSequenceNumber; /**< Sequence number. 6 + 2 = 8 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xICMPEcho_IPv6 ICMPEcho_IPv6_t;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xICMPRouterSolicitation_IPv6
|
|
{
|
|
uint8_t ucTypeOfMessage; /**< 0 + 1 = 1 */
|
|
uint8_t ucTypeOfService; /**< 1 + 1 = 2 */
|
|
uint16_t usChecksum; /**< 2 + 2 = 4 */
|
|
uint32_t ulReserved; /**< 4 + 4 = 8 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xICMPRouterSolicitation_IPv6 ICMPRouterSolicitation_IPv6_t;
|
|
|
|
#if ( ipconfigUSE_RA != 0 )
|
|
#include "pack_struct_start.h"
|
|
struct xICMPRouterAdvertisement_IPv6
|
|
{
|
|
uint8_t ucTypeOfMessage; /* 0 + 1 = 1 */
|
|
uint8_t ucTypeOfService; /* 1 + 1 = 2 */
|
|
uint16_t usChecksum; /* 2 + 2 = 4 */
|
|
uint8_t ucHopLimit; /* 4 + 1 = 5 */
|
|
uint8_t ucFlags; /* 5 + 1 = 6 */
|
|
uint16_t usLifetime; /* 6 + 2 = 8 */
|
|
uint16_t usReachableTime[ 2 ]; /* 8 + 4 = 12 */
|
|
uint16_t usRetransTime[ 2 ]; /* 12 + 4 = 16 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xICMPRouterAdvertisement_IPv6 ICMPRouterAdvertisement_IPv6_t;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xICMPPrefixOption_IPv6
|
|
{
|
|
uint8_t ucType; /* 0 + 1 = 1 */
|
|
uint8_t ucLength; /* 1 + 1 = 2 */
|
|
uint8_t ucPrefixLength; /* 2 + 1 = 3 */
|
|
uint8_t ucFlags; /* 3 + 1 = 4 */
|
|
uint32_t ulValidLifeTime; /* 4 + 4 = 8 */
|
|
uint32_t ulPreferredLifeTime; /* 8 + 4 = 12 */
|
|
uint32_t ulReserved; /* 12 + 4 = 16 */
|
|
uint8_t ucPrefix[ 16 ]; /* 16 + 16 = 32 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xICMPPrefixOption_IPv6 ICMPPrefixOption_IPv6_t;
|
|
#endif /* ipconfigUSE_RA != 0 */
|
|
|
|
/*-----------------------------------------------------------*/
|
|
/* Nested protocol packets. */
|
|
/*-----------------------------------------------------------*/
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xIP_PACKET_IPv6
|
|
{
|
|
EthernetHeader_t xEthernetHeader;
|
|
IPHeader_IPv6_t xIPHeader;
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xIP_PACKET_IPv6 IPPacket_IPv6_t;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xICMP_PACKET_IPv6
|
|
{
|
|
EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
|
|
IPHeader_IPv6_t xIPHeader; /* 14 + 40 = 54 */
|
|
ICMPHeader_IPv6_t xICMPHeaderIPv6; /* 54 + 8 = 62 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xICMP_PACKET_IPv6 ICMPPacket_IPv6_t;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xUDP_PACKET_IPv6
|
|
{
|
|
EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
|
|
IPHeader_IPv6_t xIPHeader; /* 14 + 40 = 54 */
|
|
UDPHeader_t xUDPHeader; /* 54 + 8 = 62 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xUDP_PACKET_IPv6 UDPPacket_IPv6_t;
|
|
|
|
#include "pack_struct_start.h"
|
|
struct xTCP_PACKET_IPv6
|
|
{
|
|
EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
|
|
IPHeader_IPv6_t xIPHeader; /* 14 + 40 = 54 */
|
|
TCPHeader_t xTCPHeader; /* 54 + 32 = 86 */
|
|
}
|
|
#include "pack_struct_end.h"
|
|
typedef struct xTCP_PACKET_IPv6 TCPPacket_IPv6_t;
|
|
|
|
/* prvProcessICMPMessage_IPv6() is declared in FreeRTOS_routing.c
|
|
* It handles all ICMP messages except the PING requests. */
|
|
eFrameProcessingResult_t prvProcessICMPMessage_IPv6( NetworkBufferDescriptor_t * const pxNetworkBuffer );
|
|
|
|
|
|
#if ( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
|
|
/* prepare a string which describes a socket, just for logging. */
|
|
const char * prvSocketProps( FreeRTOS_Socket_t * pxSocket );
|
|
#endif /* ipconfigHAS_DEBUG_PRINTF || ipconfigHAS_PRINTF */
|
|
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
/* *INDENT-ON* */
|
|
|
|
#endif /* FREERTOS_IP_PRIVATE_H */
|