<commit_before>//--------------------------------------------------------------------------------------------------
/**
 *  Data Channel Server's C code implementation of the support for networking APIs and
 *  functionalities.
 *
 *  Copyright (C) Sierra Wireless Inc.
 *
 */
//--------------------------------------------------------------------------------------------------

#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include "legato.h"
#include "interfaces.h"
#include "le_print.h"
#include "dcs.h"
#include "dcsNet.h"
#include "pa_dcs.h"


//--------------------------------------------------------------------------------------------------
/**
 * This define gives the max value of an IPv6 subnet prefix length, i.e. 128
 */
//--------------------------------------------------------------------------------------------------
#define IPV6_PREFIX_LENGTH_MAX (8 * 8 * 2)


//--------------------------------------------------------------------------------------------------
/**
 * The following 2 defines specify the length of the char array in which the numeric value of an
 * IPv6 subnet prefix length is. IPV6_PREFIX_LEN_STR_BYTES specifies the total byte length while
 * IPV6_PREFIX_LEN_STR_LENGTH the number of decimal digits taken by this value.
 */
//--------------------------------------------------------------------------------------------------
#define IPV6_PREFIX_LEN_STR_BYTES  4
#define IPV6_PREFIX_LEN_STR_LENGTH 3

//--------------------------------------------------------------------------------------------------
/**
 * DHCP Lease File Options. These are used as keys to search in the DHCP lease file
 */
//--------------------------------------------------------------------------------------------------
#define DEFAULT_GW_OPTION "routers"
#define DNS_ADDRESS_OPTION "domain-name-servers"

//--------------------------------------------------------------------------------------------------
/**
 * File Path Length
 */
//--------------------------------------------------------------------------------------------------
#define FILE_PATH_LENGTH_BYTES 128

//--------------------------------------------------------------------------------------------------
/**
 * Possible number of each type of IP version addresses that can be found in a lease file
 */
//--------------------------------------------------------------------------------------------------
#define MAX_NUM_DEFAULT_GATEWAY_ADDRESS_BY_TYPE 1
#define MAX_NUM_DNS_ADDRESS_BY_TYPE             2

//--------------------------------------------------------------------------------------------------
/**
 * Max length of a DHCP line to read
 */
//--------------------------------------------------------------------------------------------------
#define LEASE_FILE_MAX_LINE_LENGTH_BYTES  (DHCP_LEASE_OPTION_MAX_LEN_BYTES \
                                        + (MAX_NUM_DNS_ADDRESS_BY_TYPE*PA_DCS_IPV6_ADDR_MAX_BYTES) \
                                        + (MAX_NUM_DNS_ADDRESS_BY_TYPE*PA_DCS_IPV4_ADDR_MAX_BYTES))

//--------------------------------------------------------------------------------------------------
/**
 * Maximal length of a DHCP Lease option
 */
//--------------------------------------------------------------------------------------------------
#define DHCP_LEASE_OPTION_MAX_LEN_BYTES 50

//--------------------------------------------------------------------------------------------------
/**
 * Enumeration for DHCP Address
 */
//--------------------------------------------------------------------------------------------------
typedef enum
{
    LE_NET_DEFAULT_GATEWAY_ADDRESS,   ///< Default gateway address(es)
    LE_NET_DNS_SERVER_ADDRESS         ///< DNS server address(es)
}
DhcpAddress_t;

//--------------------------------------------------------------------------------------------------
/**
 * Data structure for backing up the system's default DNS configs
 */
//--------------------------------------------------------------------------------------------------
static pa_dcs_DnsBackup_t DnsBackup;

//--------------------------------------------------------------------------------------------------
/**
 * Data structures for backing up the system's default IPv4/v6 GW configs:
 *    DcsDefaultGwConfigDb_t: a default GW config backup db (data structure), one per client app
 *    DcsDefaultGwConfigDataDbPool: the memory pool from which DcsDefaultGwConfigDb_t is allocated
 *    DcsDefaultGwConfigDbList: the list of config backup db ordered in a lasst-in-first-out stack
 *
 * Inserting into DcsDefaultGwConfigDbList:
 *    Any new list member will be added to the start of the list, which is like the stack's top
 * Popping from DcsDefaultGwConfigDbList:
 *    When a backup db is popped for restoring config, it is popped from the start of the list to
 *    implement a last-in-first-out stack to maintain the right order
 * Changing backup config in a member already on DcsDefaultGwConfigDbList:
 *    This member will first be removed from this list, updated with the given configs, and then
 *    re-inserted back to the start of the list
 * Request for restoring the configs in a member not in the start of the list:
 *    A warning debug message will be given to the client that this config restoration is out of
 *    sequence. But then the request will still be honoured with this member removed from the list
 *    for use.
 *
 * This backup mechanism is so far implemented for default IPv4/v6 GW configs, and not DNS configs
 * yet.
 */
//--------------------------------------------------------------------------------------------------
typedef struct
{
    pa_dcs_DefaultGwBackup_t backupConfig; ///< Data structure for archiving backup configs
    le_dls_Link_t dbLink;                  ///< Double-link used to order elements as a LIFO stack
} DcsDefaultGwConfigDb_t;

static le_mem_PoolRef_t DcsDefaultGwConfigDataDbPool;
static le_dls_List_t DcsDefaultGwConfigDbList;


//--------------------------------------------------------------------------------------------------
/**
 * Retrieve the session reference of the client app which calls the corresponding le_net API to
 * perform network config management over a data channel. If the result is 0, it is valid and means
 * that the internal client le_data is the one.
 *
 * @return
 *     session reference: non-zero means a client app while 0 means le_data which is an internal
 *     client
 */
//--------------------------------------------------------------------------------------------------
le_msg_SessionRef_t DcsNetGetSessionRef
(
    void
)
{
    le_msg_SessionRef_t sessionRef = le_net_GetClientSessionRef();
    if (!sessionRef)
    {
        LE_DEBUG("Client app's sessionRef (nil) reflects it's from le_data");
    }
    return sessionRef;
}


//--------------------------------------------------------------------------------------------------
/**
 * This function searches through DcsDefaultGwConfigDbList for a matching session reference with
 * the given one in the input. If it is at the start of the list, the 2nd argument isRecent will be
 * set to true to let the function caller know.
 *
 * @return
 *     DcsDefaultGwConfigDb_t with the matching session reference. NULL if none is found.
 */
//--------------------------------------------------------------------------------------------------
static DcsDefaultGwConfigDb_t* GetDefaultGwConfigDb
(
    le_msg_SessionRef_t appSessionRef,
    bool* isRecent
)
{
    le_dls_Link_t* defGwConfigDbLinkPtr;
    DcsDefaultGwConfigDb_t* defGwConfigDbPtr;
    pa_dcs_DefaultGwBackup_t* backupDbPtr;
    *isRecent = false;

    for (defGwConfigDbLinkPtr = le_dls_Peek(&DcsDefaultGwConfigDbList); defGwConfigDbLinkPtr;
         defGwConfigDbLinkPtr = le_dls_PeekNext(&DcsDefaultGwConfigDbList, defGwConfigDbLinkPtr))
    {
        defGwConfigDbPtr = CONTAINER_OF(defGwConfigDbLinkPtr, DcsDefaultGwConfigDb_t, dbLink);
        if (!defGwConfigDbPtr)
        {
            continue;
        }
        if (!(backupDbPtr = &defGwConfigDbPtr->backupConfig))
        {
            LE_WARN("Default GW config Db missing on its Db list");
            continue;
        }
        if (backupDbPtr->appSessionRef == appSessionRef)
        {
            LE_DEBUG("Found default GW config backup for session reference %p on a queue "
                     "of %" PRIuS, appSessionRef, le_dls_NumLinks(&DcsDefaultGwConfigDbList));<commit_msg>Remove dcsNet.c code reported as dead by Coverity<commit_after>//--------------------------------------------------------------------------------------------------
/**
 *  Data Channel Server's C code implementation of the support for networking APIs and
 *  functionalities.
 *
 *  Copyright (C) Sierra Wireless Inc.
 *
 */
//--------------------------------------------------------------------------------------------------

#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include "legato.h"
#include "interfaces.h"
#include "le_print.h"
#include "dcs.h"
#include "dcsNet.h"
#include "pa_dcs.h"


//--------------------------------------------------------------------------------------------------
/**
 * This define gives the max value of an IPv6 subnet prefix length, i.e. 128
 */
//--------------------------------------------------------------------------------------------------
#define IPV6_PREFIX_LENGTH_MAX (8 * 8 * 2)


//--------------------------------------------------------------------------------------------------
/**
 * The following 2 defines specify the length of the char array in which the numeric value of an
 * IPv6 subnet prefix length is. IPV6_PREFIX_LEN_STR_BYTES specifies the total byte length while
 * IPV6_PREFIX_LEN_STR_LENGTH the number of decimal digits taken by this value.
 */
//--------------------------------------------------------------------------------------------------
#define IPV6_PREFIX_LEN_STR_BYTES  4
#define IPV6_PREFIX_LEN_STR_LENGTH 3

//--------------------------------------------------------------------------------------------------
/**
 * DHCP Lease File Options. These are used as keys to search in the DHCP lease file
 */
//--------------------------------------------------------------------------------------------------
#define DEFAULT_GW_OPTION "routers"
#define DNS_ADDRESS_OPTION "domain-name-servers"

//--------------------------------------------------------------------------------------------------
/**
 * File Path Length
 */
//--------------------------------------------------------------------------------------------------
#define FILE_PATH_LENGTH_BYTES 128

//--------------------------------------------------------------------------------------------------
/**
 * Possible number of each type of IP version addresses that can be found in a lease file
 */
//--------------------------------------------------------------------------------------------------
#define MAX_NUM_DEFAULT_GATEWAY_ADDRESS_BY_TYPE 1
#define MAX_NUM_DNS_ADDRESS_BY_TYPE             2

//--------------------------------------------------------------------------------------------------
/**
 * Max length of a DHCP line to read
 */
//--------------------------------------------------------------------------------------------------
#define LEASE_FILE_MAX_LINE_LENGTH_BYTES  (DHCP_LEASE_OPTION_MAX_LEN_BYTES \
                                        + (MAX_NUM_DNS_ADDRESS_BY_TYPE*PA_DCS_IPV6_ADDR_MAX_BYTES) \
                                        + (MAX_NUM_DNS_ADDRESS_BY_TYPE*PA_DCS_IPV4_ADDR_MAX_BYTES))

//--------------------------------------------------------------------------------------------------
/**
 * Maximal length of a DHCP Lease option
 */
//--------------------------------------------------------------------------------------------------
#define DHCP_LEASE_OPTION_MAX_LEN_BYTES 50

//--------------------------------------------------------------------------------------------------
/**
 * Enumeration for DHCP Address
 */
//--------------------------------------------------------------------------------------------------
typedef enum
{
    LE_NET_DEFAULT_GATEWAY_ADDRESS,   ///< Default gateway address(es)
    LE_NET_DNS_SERVER_ADDRESS         ///< DNS server address(es)
}
DhcpAddress_t;

//--------------------------------------------------------------------------------------------------
/**
 * Data structure for backing up the system's default DNS configs
 */
//--------------------------------------------------------------------------------------------------
static pa_dcs_DnsBackup_t DnsBackup;

//--------------------------------------------------------------------------------------------------
/**
 * Data structures for backing up the system's default IPv4/v6 GW configs:
 *    DcsDefaultGwConfigDb_t: a default GW config backup db (data structure), one per client app
 *    DcsDefaultGwConfigDataDbPool: the memory pool from which DcsDefaultGwConfigDb_t is allocated
 *    DcsDefaultGwConfigDbList: the list of config backup db ordered in a lasst-in-first-out stack
 *
 * Inserting into DcsDefaultGwConfigDbList:
 *    Any new list member will be added to the start of the list, which is like the stack's top
 * Popping from DcsDefaultGwConfigDbList:
 *    When a backup db is popped for restoring config, it is popped from the start of the list to
 *    implement a last-in-first-out stack to maintain the right order
 * Changing backup config in a member already on DcsDefaultGwConfigDbList:
 *    This member will first be removed from this list, updated with the given configs, and then
 *    re-inserted back to the start of the list
 * Request for restoring the configs in a member not in the start of the list:
 *    A warning debug message will be given to the client that this config restoration is out of
 *    sequence. But then the request will still be honoured with this member removed from the list
 *    for use.
 *
 * This backup mechanism is so far implemented for default IPv4/v6 GW configs, and not DNS configs
 * yet.
 */
//--------------------------------------------------------------------------------------------------
typedef struct
{
    pa_dcs_DefaultGwBackup_t backupConfig; ///< Data structure for archiving backup configs
    le_dls_Link_t dbLink;                  ///< Double-link used to order elements as a LIFO stack
} DcsDefaultGwConfigDb_t;

static le_mem_PoolRef_t DcsDefaultGwConfigDataDbPool;
static le_dls_List_t DcsDefaultGwConfigDbList;


//--------------------------------------------------------------------------------------------------
/**
 * Retrieve the session reference of the client app which calls the corresponding le_net API to
 * perform network config management over a data channel. If the result is 0, it is valid and means
 * that the internal client le_data is the one.
 *
 * @return
 *     session reference: non-zero means a client app while 0 means le_data which is an internal
 *     client
 */
//--------------------------------------------------------------------------------------------------
le_msg_SessionRef_t DcsNetGetSessionRef
(
    void
)
{
    le_msg_SessionRef_t sessionRef = le_net_GetClientSessionRef();
    if (!sessionRef)
    {
        LE_DEBUG("Client app's sessionRef (nil) reflects it's from le_data");
    }
    return sessionRef;
}


//--------------------------------------------------------------------------------------------------
/**
 * This function searches through DcsDefaultGwConfigDbList for a matching session reference with
 * the given one in the input. If it is at the start of the list, the 2nd argument isRecent will be
 * set to true to let the function caller know.
 *
 * @return
 *     DcsDefaultGwConfigDb_t with the matching session reference. NULL if none is found.
 */
//--------------------------------------------------------------------------------------------------
static DcsDefaultGwConfigDb_t* GetDefaultGwConfigDb
(
    le_msg_SessionRef_t appSessionRef,
    bool* isRecent
)
{
    le_dls_Link_t* defGwConfigDbLinkPtr;
    DcsDefaultGwConfigDb_t* defGwConfigDbPtr;
    pa_dcs_DefaultGwBackup_t* backupDbPtr;
    *isRecent = false;

    for (defGwConfigDbLinkPtr = le_dls_Peek(&DcsDefaultGwConfigDbList); defGwConfigDbLinkPtr;
         defGwConfigDbLinkPtr = le_dls_PeekNext(&DcsDefaultGwConfigDbList, defGwConfigDbLinkPtr))
    {
        defGwConfigDbPtr = CONTAINER_OF(defGwConfigDbLinkPtr, DcsDefaultGwConfigDb_t, dbLink);
        if (!(backupDbPtr = &defGwConfigDbPtr->backupConfig))
        {
            LE_WARN("Default GW config Db missing on its Db list");
            continue;
        }
        if (backupDbPtr->appSessionRef == appSessionRef)
        {
            LE_DEBUG("Found default GW config backup for session reference %p on a queue "
                     "of %" PRIuS, appSessionRef, le_dls_NumLinks(&DcsDefaultGwConfigDbList));
{'fraction_non_alphanumeric': 0.3541008993984156, 'fraction_numerical': 0.003812019774852582, 'mean_word_length': 1.150909556751217, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3427071', 'n_tokens_mistral': 3858, 'n_tokens_neox': 3729, 'n_words': 1245}