AzureMXChip/MXCHIPAZ3166/core/lib/netxduo/addons/dhcp/nxd_dhcpv6_server.c
UINT _nx_dhcpv6_add_option_requests(NX_DHCPV6_SERVER *dhcpv6_server_ptr, NX_DHCPV6_CLIENT *dhcpv6_client_ptr, 
                                   UCHAR *buffer_ptr, UINT *index) 
{

USHORT                  i, j;
ULONG                   message_word;
UINT                    available_payload;
NXD_ADDRESS             *dns_server_address;
NX_DHCPV6_SERVER_OPTIONREQUEST *dhcpv6_option_ptr;


    dhcpv6_option_ptr = &dhcpv6_client_ptr -> nx_dhcpv6_option_request;

    /* 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;

    /* Process up to the maximum allowed options.  */
    for(i = 0; i < NX_DHCPV6_MAX_OPTION_REQUEST_OPTIONS; i++)
    {

        /* Check for the end of the list. */
        if (dhcpv6_option_ptr -> nx_op_request[i] == 0)
        {

            /* No more options. */
            break;
        }

         /* Is this the DNS server option? */
        if (dhcpv6_option_ptr -> nx_op_request[i] == NX_DHCPV6_RFC_DNS_SERVER_OPTION)
        {

            /*  Create an option containing a single DNS server address. */
            dhcpv6_option_ptr -> nx_option_length =  4 * sizeof(ULONG);

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

                /* It won't. */
                return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
            }

            message_word = (ULONG)dhcpv6_option_ptr -> nx_op_request[i] << 16;
            message_word |= dhcpv6_option_ptr -> nx_option_length;

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

            /* Copy the option request option header to the packet. */
            memcpy(buffer_ptr + *index, &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
            *index += (ULONG)sizeof(ULONG);

            dns_server_address = &dhcpv6_server_ptr -> nx_dhcpv6_dns_ip_address;
            for (j = 0; j < 4; j++)
            {

                message_word = dns_server_address -> nxd_ip_address.v6[j];

                NX_CHANGE_ULONG_ENDIAN(message_word);

                memcpy(buffer_ptr + *index, &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */

                *index += (ULONG)sizeof(ULONG); 
            }

            /* Update the available payload.  */
            available_payload = (UINT)(available_payload - (UINT)(dhcpv6_option_ptr -> nx_option_length + 4));
        }
        /* Does the DHCPv6 server have an extended option handler? */
        else if (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler_extended)
        {

            /* Yes, so call it.  This handler shall fill the buffer with the requested
               option data (if available).  

               Note: The handler must update the index pointing to the end of data in the buffer
               after it inserts the data. This is done for the DNS server option above.  */
            (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler_extended)(dhcpv6_server_ptr, dhcpv6_option_ptr -> nx_op_request[i], buffer_ptr, index, available_payload);

            /* Check if exceed the payload.  */
            if ((NX_IPv6_UDP_PACKET + *index) <= dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size)
            {

                /* Update the available payload.  */
                available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size -
                                    NX_IPv6_UDP_PACKET - *index;
            }
            else
            {
                return (NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD);
            }
        }
        /* Does the DHCPv6 server have an option handler? */
        else if (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler)
        {

            /* Yes, so call it.  This handler shall fill the buffer with the requested
               option data (if available).  

               Note: The handler must update the index pointing to the end of data in the buffer
               after it inserts the data. This is done for the DNS server option above.  */
            (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler)(dhcpv6_server_ptr, dhcpv6_option_ptr -> nx_op_request[i], buffer_ptr, index);

            /* Check if exceed the payload.  */
            if ((NX_IPv6_UDP_PACKET + *index) <= dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size)
            {

                /* Update the available payload.  */
                available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size -
                                    NX_IPv6_UDP_PACKET - *index;
            }
            else
            {
                return (NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD);
            }

        }
    }

    return NX_SUCCESS;
}
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_dhcpv6_add_option_requests                      PORTABLE C      */
/*                                                           6.1          */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Yuxin Zhou, Microsoft Corporation                                   */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function adds the 'option request' option to the server reply  */
/*    packet based on the options requested from the client, and what     */
/*    options the DHCPv6 server is configured to supply.                  */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    dhcpv6_server_ptr                 Pointer to DHCPV6 server instance */
/*    dhcpv6_client_ptr                 Pointer to DHCPV6 client instance */
/*    buffer_ptr                        Pointer to packet buffer          */
/*    index                             Location into buffer to write data*/
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    NX_SUCCESS                        Successful completion status      */
/*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
/*                                      Not enough room for the option    */
/*                                       request in the packet payload    */
/*  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_option_requests                      PORTABLE C
6.1
AUTHOR

Yuxin Zhou, Microsoft Corporation

DESCRIPTION

This function adds the 'option request' option to the server reply
packet based on the options requested from the client, and what
options the DHCPv6 server is configured to supply.

INPUT

dhcpv6_server_ptr                 Pointer to DHCPV6 server instance
dhcpv6_client_ptr                 Pointer to DHCPV6 client instance
buffer_ptr                        Pointer to packet buffer
index                             Location into buffer to write data

OUTPUT

NX_SUCCESS                        Successful completion status
NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD
Not enough room for the option
request in the packet payload
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_option_requests PORTABLE C 6 . 1 AUTHOR Yuxin Zhou Microsoft Corporation DESCRIPTION This function adds the ' option request ' option to the server reply packet based on the options requested from the client and what options the DHCPv6 server is configured to supply . INPUT dhcpv6_server_ptr Pointer to DHCPV6 server instance dhcpv6_client_ptr Pointer to DHCPV6 client instance buffer_ptr Pointer to packet buffer index Location into buffer to write data OUTPUT NX_SUCCESS Successful completion status NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD Not enough room for the option request in the packet payload 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_option_requests(NX_DHCPV6_SERVER *dhcpv6_server_ptr, NX_DHCPV6_CLIENT *dhcpv6_client_ptr, 
                                   UCHAR *buffer_ptr, UINT *index) 
{
USHORT                  i, j;
ULONG                   message_word;
UINT                    available_payload;
NXD_ADDRESS             *dns_server_address;
NX_DHCPV6_SERVER_OPTIONREQUEST *dhcpv6_option_ptr;
    dhcpv6_option_ptr = &dhcpv6_client_ptr -> nx_dhcpv6_option_request;
    available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size - 
                        NX_IPv6_UDP_PACKET - *index;
    for(i = 0; i < NX_DHCPV6_MAX_OPTION_REQUEST_OPTIONS; i++)
    {
        if (dhcpv6_option_ptr -> nx_op_request[i] == 0)
        {
            break;
        }
        if (dhcpv6_option_ptr -> nx_op_request[i] == NX_DHCPV6_RFC_DNS_SERVER_OPTION)
        {
            dhcpv6_option_ptr -> nx_option_length =  4 * sizeof(ULONG);
            if (available_payload < (UINT)(dhcpv6_option_ptr -> nx_option_length + 4)) 
            {
                return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
            }
            message_word = (ULONG)dhcpv6_option_ptr -> nx_op_request[i] << 16;
            message_word |= dhcpv6_option_ptr -> nx_option_length;
            NX_CHANGE_ULONG_ENDIAN(message_word);
            memcpy(buffer_ptr + *index, &message_word, sizeof(ULONG)); 
            *index += (ULONG)sizeof(ULONG);
            dns_server_address = &dhcpv6_server_ptr -> nx_dhcpv6_dns_ip_address;
            for (j = 0; j < 4; j++)
            {
                message_word = dns_server_address -> nxd_ip_address.v6[j];
                NX_CHANGE_ULONG_ENDIAN(message_word);
                memcpy(buffer_ptr + *index, &message_word, sizeof(ULONG)); 
                *index += (ULONG)sizeof(ULONG); 
            }
            available_payload = (UINT)(available_payload - (UINT)(dhcpv6_option_ptr -> nx_option_length + 4));
        }
        else if (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler_extended)
        {
            (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler_extended)(dhcpv6_server_ptr, dhcpv6_option_ptr -> nx_op_request[i], buffer_ptr, index, available_payload);
            if ((NX_IPv6_UDP_PACKET + *index) <= dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size)
            {
                available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size -
                                    NX_IPv6_UDP_PACKET - *index;
            }
            else
            {
                return (NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD);
            }
        }
        else if (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler)
        {
            (dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler)(dhcpv6_server_ptr, dhcpv6_option_ptr -> nx_op_request[i], buffer_ptr, index);
            if ((NX_IPv6_UDP_PACKET + *index) <= dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size)
            {
                available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size -
                                    NX_IPv6_UDP_PACKET - *index;
            }
            else
            {
                return (NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD);
            }
        }
    }
    return NX_SUCCESS;
}
UINT _nx_dhcpv6_add_option_requests ( NX_DHCPV6_SERVER * dhcpv6_server_ptr , NX_DHCPV6_CLIENT * dhcpv6_client_ptr , UCHAR * buffer_ptr , UINT * index ) { USHORT i , j ; ULONG message_word ; UINT available_payload ; NXD_ADDRESS * dns_server_address ; NX_DHCPV6_SERVER_OPTIONREQUEST * dhcpv6_option_ptr ; dhcpv6_option_ptr = & dhcpv6_client_ptr -> nx_dhcpv6_option_request ; available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size - NX_IPv6_UDP_PACKET - * index ; for ( i = 0 ; i < NX_DHCPV6_MAX_OPTION_REQUEST_OPTIONS ; i ++ ) { if ( dhcpv6_option_ptr -> nx_op_request [ i ] == 0 ) { break ; } if ( dhcpv6_option_ptr -> nx_op_request [ i ] == NX_DHCPV6_RFC_DNS_SERVER_OPTION ) { dhcpv6_option_ptr -> nx_option_length = 4 * sizeof ( ULONG ) ; if ( available_payload < ( UINT ) ( dhcpv6_option_ptr -> nx_option_length + 4 ) ) { return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD ; } message_word = ( ULONG ) dhcpv6_option_ptr -> nx_op_request [ i ] << 16 ; message_word |= dhcpv6_option_ptr -> nx_option_length ; NX_CHANGE_ULONG_ENDIAN ( message_word ) ; memcpy ( buffer_ptr + * index , & message_word , sizeof ( ULONG ) ) ; * index += ( ULONG ) sizeof ( ULONG ) ; dns_server_address = & dhcpv6_server_ptr -> nx_dhcpv6_dns_ip_address ; for ( j = 0 ; j < 4 ; j ++ ) { message_word = dns_server_address -> nxd_ip_address . v6 [ j ] ; NX_CHANGE_ULONG_ENDIAN ( message_word ) ; memcpy ( buffer_ptr + * index , & message_word , sizeof ( ULONG ) ) ; * index += ( ULONG ) sizeof ( ULONG ) ; } available_payload = ( UINT ) ( available_payload - ( UINT ) ( dhcpv6_option_ptr -> nx_option_length + 4 ) ) ; } else if ( dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler_extended ) { ( dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler_extended ) ( dhcpv6_server_ptr , dhcpv6_option_ptr -> nx_op_request [ i ] , buffer_ptr , index , available_payload ) ; if ( ( NX_IPv6_UDP_PACKET + * index ) <= dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size ) { available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size - NX_IPv6_UDP_PACKET - * index ; } else { return ( NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD ) ; } } else if ( dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler ) { ( dhcpv6_server_ptr -> nx_dhcpv6_server_option_request_handler ) ( dhcpv6_server_ptr , dhcpv6_option_ptr -> nx_op_request [ i ] , buffer_ptr , index ) ; if ( ( NX_IPv6_UDP_PACKET + * index ) <= dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size ) { available_payload = dhcpv6_server_ptr -> nx_dhcpv6_packet_pool_ptr -> nx_packet_pool_payload_size - NX_IPv6_UDP_PACKET - * index ; } else { return ( NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD ) ; } } } return NX_SUCCESS ; }
FUNCTION                                               RELEASE
FUNCTION RELEASE
/* Compute the available payload in the packet buffer. */ /* Process up to the maximum allowed options.  */ /* Check for the end of the list. */ /* No more options. */ /* Is this the DNS server option? */ /*  Create an option containing a single DNS server address. */ /* Check if the option request option will fit in the packet buffer. */ /* It won't. */ /* Adjust for endianness. */ /* Copy the option request option header to the packet. */ /* Use case of memcpy is verified. */ /* Use case of memcpy is verified. */ /* Update the available payload.  */ /* Does the DHCPv6 server have an extended option handler? */ /* Yes, so call it.  This handler shall fill the buffer with the requested
               option data (if available).  

               Note: The handler must update the index pointing to the end of data in the buffer
               after it inserts the data. This is done for the DNS server option above.  */ /* Check if exceed the payload.  */ /* Update the available payload.  */ /* Does the DHCPv6 server have an option handler? */ /* Yes, so call it.  This handler shall fill the buffer with the requested
               option data (if available).  

               Note: The handler must update the index pointing to the end of data in the buffer
               after it inserts the data. This is done for the DNS server option above.  */ /* Check if exceed the payload.  */ /* Update the available payload.  */