AzureMXChip/MXCHIPAZ3166/core/lib/netxduo/addons/dhcp/nxd_dhcpv6_server.c
UINT  _nx_dhcpv6_add_duid(NX_DHCPV6_SERVER *dhcpv6_server_ptr, NX_DHCPV6_SVR_DUID *dhcpv6_duid_ptr, UCHAR *buffer_ptr, UINT *index, UINT duid_type)
{

ULONG message_word;
UINT  available_payload;

    NX_PARAMETER_NOT_USED(duid_type);

    /* Clear memory to make the message header. */
    memset(&message_word, 0, sizeof(ULONG));
    
    /* Compile the header from the DUID. */
    message_word = (ULONG)(dhcpv6_duid_ptr -> nx_op_code << 16);
    message_word |= (dhcpv6_duid_ptr -> nx_option_length);

    /* Compute the available payload in the packet buffer. */
    available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size - 
                        NX_IPv6_UDP_PACKET - *index;

    /* Check if the DUID will fit in the packet buffer. */
    if (available_payload < (UINT)(dhcpv6_duid_ptr -> nx_option_length + 4)) 
    {

        /* Hmmm... not enough! Can't do it. */
        return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
    }

    /* Adjust for endianness. */
    NX_CHANGE_ULONG_ENDIAN(message_word);

    /* Copy first half of the DUID option to packet buffer. */
    memcpy(buffer_ptr + *index, &message_word, sizeof(UINT)); /* Use case of memcpy is verified. */
    *index += (ULONG)sizeof(UINT);

    memset(&message_word, 0, sizeof(ULONG));

    /* Set  up the rest of the Client DUID header. */
    message_word = (ULONG)(dhcpv6_duid_ptr -> nx_duid_type << 16);
    message_word |= dhcpv6_duid_ptr -> nx_hardware_type;

    /* Adjust for endianness. */
    NX_CHANGE_ULONG_ENDIAN(message_word);

    /* Set up the DUID option. */
    memcpy(buffer_ptr + *index, &message_word, sizeof(UINT)); /* Use case of memcpy is verified. */
    *index += (ULONG)sizeof(UINT);

    /* Adjust for endianness. */
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_duid_time);
    NX_CHANGE_USHORT_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_msw);
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_lsw);

    /* Include the 'time' field if this is a Link layer time DUID type. */
    if (dhcpv6_duid_ptr -> nx_duid_type == NX_DHCPV6_SERVER_DUID_TYPE_LINK_TIME)
    {

        memcpy(buffer_ptr + *index, &(dhcpv6_duid_ptr -> nx_duid_time), sizeof(ULONG)); /* Use case of memcpy is verified. */
        *index += (ULONG)sizeof(ULONG);
    }
   
    /* Copy the rest of the DUID header. */
    memcpy(buffer_ptr + *index, &(dhcpv6_duid_ptr -> nx_link_layer_address_msw), sizeof(USHORT)); /* Use case of memcpy is verified. */
    *index += (ULONG)sizeof(USHORT);

    memcpy(buffer_ptr + *index, &(dhcpv6_duid_ptr -> nx_link_layer_address_lsw), sizeof(ULONG)); /* Use case of memcpy is verified. */
    *index += (ULONG)sizeof(ULONG);

    /* Swap bytes back to original endianness. */
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_lsw);
    NX_CHANGE_USHORT_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_msw);
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_duid_time);

    return NX_SUCCESS;
}
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_dhcpv6_add_duid                                 PORTABLE C      */
/*                                                           6.1          */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Yuxin Zhou, Microsoft Corporation                                   */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function adds a DHCPv6 DUID to the server response  packet     */
/*    based on the input DUID and the DUID type (client or server).       */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    dhcpv6_server_ptr                 Pointer to DHCPV6 server instance */
/*    dhcpv6_duid_ptr                   Pointer to DHCPV6 DUID instance   */
/*    buffer                            Pointer to packet buffer          */
/*    index                             Location where to add DUID        */
/*    duid_type                         Indicate client or serve DUID     */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    NX_SUCCESS                        Successful completion status      */
/*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
/*                                      Packet buffer too small for DUID  */
/*  CALLS                                                                 */
/*                                                                        */
/*    memset                            Clears specified area of memory   */
/*    memcpy                            Copies specified area of memory   */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    _nx_dhcpv6_send_request           Compiles and sends the Server     */
/*                                            DHCPv6 response             */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
/*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
/*                                            verified memcpy use cases,  */
/*                                            resulting in version 6.1    */
/*                                                                        */
/**************************************************************************/
FUNCTION                                               RELEASE

_nx_dhcpv6_add_duid                                 PORTABLE C
6.1
AUTHOR

Yuxin Zhou, Microsoft Corporation

DESCRIPTION

This function adds a DHCPv6 DUID to the server response  packet
based on the input DUID and the DUID type (client or server).

INPUT

dhcpv6_server_ptr                 Pointer to DHCPV6 server instance
dhcpv6_duid_ptr                   Pointer to DHCPV6 DUID instance
buffer                            Pointer to packet buffer
index                             Location where to add DUID
duid_type                         Indicate client or serve DUID

OUTPUT

NX_SUCCESS                        Successful completion status
NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD
Packet buffer too small for DUID
CALLS

memset                            Clears specified area of memory
memcpy                            Copies specified area of memory

CALLED BY

_nx_dhcpv6_send_request           Compiles and sends the Server
DHCPv6 response

RELEASE HISTORY

DATE              NAME                      DESCRIPTION

05-19-2020     Yuxin Zhou               Initial Version 6.0
09-30-2020     Yuxin Zhou               Modified comment(s), and
verified memcpy use cases,
resulting in version 6.1
FUNCTION RELEASE _nx_dhcpv6_add_duid PORTABLE C 6 . 1 AUTHOR Yuxin Zhou Microsoft Corporation DESCRIPTION This function adds a DHCPv6 DUID to the server response packet based on the input DUID and the DUID type ( client or server ) . INPUT dhcpv6_server_ptr Pointer to DHCPV6 server instance dhcpv6_duid_ptr Pointer to DHCPV6 DUID instance buffer Pointer to packet buffer index Location where to add DUID duid_type Indicate client or serve DUID OUTPUT NX_SUCCESS Successful completion status NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD Packet buffer too small for DUID CALLS memset Clears specified area of memory memcpy Copies specified area of memory CALLED BY _nx_dhcpv6_send_request Compiles and sends the Server DHCPv6 response RELEASE HISTORY DATE NAME DESCRIPTION 05 - 19 - 2020 Yuxin Zhou Initial Version 6 . 0 09 - 30 - 2020 Yuxin Zhou Modified comment ( s ) and verified memcpy use cases resulting in version 6 . 1
UINT  _nx_dhcpv6_add_duid(NX_DHCPV6_SERVER *dhcpv6_server_ptr, NX_DHCPV6_SVR_DUID *dhcpv6_duid_ptr, UCHAR *buffer_ptr, UINT *index, UINT duid_type)
{
ULONG message_word;
UINT  available_payload;
    NX_PARAMETER_NOT_USED(duid_type);
    memset(&message_word, 0, sizeof(ULONG));
    message_word = (ULONG)(dhcpv6_duid_ptr -> nx_op_code << 16);
    message_word |= (dhcpv6_duid_ptr -> nx_option_length);
    available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size - 
                        NX_IPv6_UDP_PACKET - *index;
    if (available_payload < (UINT)(dhcpv6_duid_ptr -> nx_option_length + 4)) 
    {
        return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
    }
    NX_CHANGE_ULONG_ENDIAN(message_word);
    memcpy(buffer_ptr + *index, &message_word, sizeof(UINT)); 
    *index += (ULONG)sizeof(UINT);
    memset(&message_word, 0, sizeof(ULONG));
    message_word = (ULONG)(dhcpv6_duid_ptr -> nx_duid_type << 16);
    message_word |= dhcpv6_duid_ptr -> nx_hardware_type;
    NX_CHANGE_ULONG_ENDIAN(message_word);
    memcpy(buffer_ptr + *index, &message_word, sizeof(UINT)); 
    *index += (ULONG)sizeof(UINT);
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_duid_time);
    NX_CHANGE_USHORT_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_msw);
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_lsw);
    if (dhcpv6_duid_ptr -> nx_duid_type == NX_DHCPV6_SERVER_DUID_TYPE_LINK_TIME)
    {
        memcpy(buffer_ptr + *index, &(dhcpv6_duid_ptr -> nx_duid_time), sizeof(ULONG)); 
        *index += (ULONG)sizeof(ULONG);
    }
    memcpy(buffer_ptr + *index, &(dhcpv6_duid_ptr -> nx_link_layer_address_msw), sizeof(USHORT)); 
    *index += (ULONG)sizeof(USHORT);
    memcpy(buffer_ptr + *index, &(dhcpv6_duid_ptr -> nx_link_layer_address_lsw), sizeof(ULONG)); 
    *index += (ULONG)sizeof(ULONG);
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_lsw);
    NX_CHANGE_USHORT_ENDIAN(dhcpv6_duid_ptr -> nx_link_layer_address_msw);
    NX_CHANGE_ULONG_ENDIAN(dhcpv6_duid_ptr -> nx_duid_time);
    return NX_SUCCESS;
}
UINT _nx_dhcpv6_add_duid ( NX_DHCPV6_SERVER * dhcpv6_server_ptr , NX_DHCPV6_SVR_DUID * dhcpv6_duid_ptr , UCHAR * buffer_ptr , UINT * index , UINT duid_type ) { ULONG message_word ; UINT available_payload ; NX_PARAMETER_NOT_USED ( duid_type ) ; memset ( & message_word , 0 , sizeof ( ULONG ) ) ; message_word = ( ULONG ) ( dhcpv6_duid_ptr -> nx_op_code << 16 ) ; message_word |= ( dhcpv6_duid_ptr -> nx_option_length ) ; available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size - NX_IPv6_UDP_PACKET - * index ; if ( available_payload < ( UINT ) ( dhcpv6_duid_ptr -> nx_option_length + 4 ) ) { return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD ; } NX_CHANGE_ULONG_ENDIAN ( message_word ) ; memcpy ( buffer_ptr + * index , & message_word , sizeof ( UINT ) ) ; * index += ( ULONG ) sizeof ( UINT ) ; memset ( & message_word , 0 , sizeof ( ULONG ) ) ; message_word = ( ULONG ) ( dhcpv6_duid_ptr -> nx_duid_type << 16 ) ; message_word |= dhcpv6_duid_ptr -> nx_hardware_type ; NX_CHANGE_ULONG_ENDIAN ( message_word ) ; memcpy ( buffer_ptr + * index , & message_word , sizeof ( UINT ) ) ; * index += ( ULONG ) sizeof ( UINT ) ; NX_CHANGE_ULONG_ENDIAN ( dhcpv6_duid_ptr -> nx_duid_time ) ; NX_CHANGE_USHORT_ENDIAN ( dhcpv6_duid_ptr -> nx_link_layer_address_msw ) ; NX_CHANGE_ULONG_ENDIAN ( dhcpv6_duid_ptr -> nx_link_layer_address_lsw ) ; if ( dhcpv6_duid_ptr -> nx_duid_type == NX_DHCPV6_SERVER_DUID_TYPE_LINK_TIME ) { memcpy ( buffer_ptr + * index , & ( dhcpv6_duid_ptr -> nx_duid_time ) , sizeof ( ULONG ) ) ; * index += ( ULONG ) sizeof ( ULONG ) ; } memcpy ( buffer_ptr + * index , & ( dhcpv6_duid_ptr -> nx_link_layer_address_msw ) , sizeof ( USHORT ) ) ; * index += ( ULONG ) sizeof ( USHORT ) ; memcpy ( buffer_ptr + * index , & ( dhcpv6_duid_ptr -> nx_link_layer_address_lsw ) , sizeof ( ULONG ) ) ; * index += ( ULONG ) sizeof ( ULONG ) ; NX_CHANGE_ULONG_ENDIAN ( dhcpv6_duid_ptr -> nx_link_layer_address_lsw ) ; NX_CHANGE_USHORT_ENDIAN ( dhcpv6_duid_ptr -> nx_link_layer_address_msw ) ; NX_CHANGE_ULONG_ENDIAN ( dhcpv6_duid_ptr -> nx_duid_time ) ; return NX_SUCCESS ; }
FUNCTION                                               RELEASE
FUNCTION RELEASE
/* Clear memory to make the message header. */ /* Compile the header from the DUID. */ /* Compute the available payload in the packet buffer. */ /* Check if the DUID will fit in the packet buffer. */ /* Hmmm... not enough! Can't do it. */ /* Adjust for endianness. */ /* Copy first half of the DUID option to packet buffer. */ /* Use case of memcpy is verified. */ /* Set  up the rest of the Client DUID header. */ /* Adjust for endianness. */ /* Set up the DUID option. */ /* Use case of memcpy is verified. */ /* Adjust for endianness. */ /* Include the 'time' field if this is a Link layer time DUID type. */ /* Use case of memcpy is verified. */ /* Copy the rest of the DUID header. */ /* Use case of memcpy is verified. */ /* Use case of memcpy is verified. */ /* Swap bytes back to original endianness. */