media/webrtc/signaling/src/sipcc/core/src-common/util_string.c
author Phil Ringnalda <philringnalda@gmail.com>
Mon, 08 Dec 2014 20:53:07 -0800
changeset 218811 960303b07c909e69db87467d0b499351d65c82af
permissions -rw-r--r--
Backed out 10 changesets (bug 1091242) for Android/b2g non-unified build bustage CLOSED TREE Backed out changeset 7f72b55c5de7 (bug 1091242) Backed out changeset f1501aa24397 (bug 1091242) Backed out changeset 7fde5994aee5 (bug 1091242) Backed out changeset 59b415714087 (bug 1091242) Backed out changeset dadb65fedc08 (bug 1091242) Backed out changeset 21be81424e4e (bug 1091242) Backed out changeset 498fb1dafba5 (bug 1091242) Backed out changeset 8d0653eb85ab (bug 1091242) Backed out changeset c82d484e135a (bug 1091242) Backed out changeset 3e0c8932f1b1 (bug 1091242)

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <errno.h>
#include <limits.h>

#include "cpr_types.h"
#include "cpr_stdio.h"
#include "cpr_stdlib.h"
#include "cpr_socket.h"
#include "cpr_in.h"
#include "util_string.h"
/*
 *  Conver IP address into dotted format or colon format.
 *
 *  @param addr_str : string to hold IP
 *         addr     : pointer to the IP address
 *
 *  @return  none
 *
 *  @pre     none
 *
 */

void
ipaddr2dotted (char *addr_str, cpr_ip_addr_t *addr)
{
    if (addr_str)
    {
        switch (addr->type) {
        case CPR_IP_ADDR_IPV4 :
        sprintf(addr_str, "%u.%u.%u.%u",
                (addr->u.ip4 >> 24) & 0xFF,
                (addr->u.ip4 >> 16) & 0xFF,
                (addr->u.ip4 >> 8)  & 0xFF,
                (addr->u.ip4)       & 0xFF);
            break;
        case CPR_IP_ADDR_IPV6:
        sprintf(addr_str, "[%x:%x:%x:%x:%x:%x:%x:%x]",
                (addr->u.ip6.addr.base16[7]),
                (addr->u.ip6.addr.base16[6]),
                (addr->u.ip6.addr.base16[5]),
                (addr->u.ip6.addr.base16[4]),
                (addr->u.ip6.addr.base16[3]),
                (addr->u.ip6.addr.base16[2]),
                (addr->u.ip6.addr.base16[1]),
                (addr->u.ip6.addr.base16[0]));

            break;
        default:
            break;
        }


    }
}

/*
 *  Convert IP address to appropriate format dotted,or with colon
 *
 *  @param addr_str ip address string
 *
 *  @return  address
 *
 *  @pre      none
 *
 */

uint32_t
dotted2ipaddr (const char *addr_str)
{
    uint32_t    address = 0;
    const char *p = NULL;
    char        section_str[3];
    int         sections[4];
    int         section;
    int         i;
    long        strtoul_result;
    char       *strtoul_end;

    /* Check args */
    if ((!addr_str) || (addr_str[0] == '\0'))
    {
        return 0xFFFFFFFF;
    }

    /* Init */
    for (i = 0; i < 4; i++)
    {
        sections[i] = 0;
    }
    p = addr_str;

    /* Remove leading blanks */
    while ((*p == ' ') || (*p == '\t') || (*p == '\n') || (*p == '\r'))
    {
        p++;
    }

    for (section = 0; section < 4; section++)
    {
        i = 0;
        section_str[0] = '\0';
        section_str[1] = '\0';
        section_str[2] = '\0';
        while ((*p != '.') && (i < 3)) {
            section_str[i] = *p;
            i++;
            p++;
        }

        errno = 0;
        strtoul_result = strtoul(section_str, &strtoul_end, 10);

        if (errno || section_str == strtoul_end ||
            strtoul_result > 255) {
            return 0xFFFFFFFF;
        }

        sections[section] = (int) strtoul_result;

        address = address | (sections[section]<<((3-section)*8));
        p++;
    }

    return address;
}

/*
 * ntohl function wrapper for both IPv4 and Ipv6
 *
 *  @param ip_addr_in, ip_addr_out : IP addresses
 *
 *  @return  none
 *
 *  @pre none
 *
 */

void util_ntohl (cpr_ip_addr_t *ip_addr_out, cpr_ip_addr_t *ip_addr_in)
{
    int i,j;
    unsigned char tmp;

    ip_addr_out->type = ip_addr_in->type;

    if (ip_addr_in->type == CPR_IP_ADDR_IPV4) {

        ip_addr_out->u.ip4 = ntohl(ip_addr_in->u.ip4);

    } else {
        //to do IPv6: Add ntohl functionality for ipv6.

        if (ip_addr_out == ip_addr_in) {
            for (i=0, j=15; i<8; i++, j--) {
                tmp  = ip_addr_out->u.ip6.addr.base8[j];
                ip_addr_out->u.ip6.addr.base8[j] = ip_addr_in->u.ip6.addr.base8[i];
                ip_addr_in->u.ip6.addr.base8[i] = tmp;
            }
        } else {
            for (i=0, j=15; i<16; i++, j--) {
                ip_addr_out->u.ip6.addr.base8[j] = ip_addr_in->u.ip6.addr.base8[i];
            }
        }
    }
}

/*
 *  Check if the IP address passed is valid. For IPv4& IPv6 check if value 0 if so
 *   return FALSE. If the type is CPR_IP_ADDR_INVALID or any other non defined type
 *   return FALSE.
 *
 *
 *  @param ip_addr  IP address
 *
 *  @return  boolean False if not a valid IP, or else true
 *
 *  @pre     none
 *
 */

boolean util_check_if_ip_valid (cpr_ip_addr_t *ip_addr)
{
    if (ip_addr->type == CPR_IP_ADDR_INVALID) {
        return(FALSE);
    }
    if (ip_addr->type == CPR_IP_ADDR_IPV4 &&
        ip_addr->u.ip4 == 0) {

        return(FALSE);
    }

    if ((ip_addr->type == CPR_IP_ADDR_IPV6) &&
        (ip_addr->u.ip6.addr.base16[7] == 0) &&
        (ip_addr->u.ip6.addr.base16[6] == 0) &&
        (ip_addr->u.ip6.addr.base16[5] == 0) &&
        (ip_addr->u.ip6.addr.base16[4] == 0) &&
        (ip_addr->u.ip6.addr.base16[3] == 0) &&
        (ip_addr->u.ip6.addr.base16[2] == 0) &&
        (ip_addr->u.ip6.addr.base16[1] == 0) &&
        (ip_addr->u.ip6.addr.base16[0] == 0)) {

        return(FALSE);
    }

    if ((ip_addr->type != CPR_IP_ADDR_INVALID) &&
        (ip_addr->type != CPR_IP_ADDR_IPV4) &&
        (ip_addr->type != CPR_IP_ADDR_IPV6)) {

        return(FALSE);
    }

    return(TRUE);
}

/*
 *  Compare 2 IP addresses
 *
 *  @param ip_addr1 & ip_addr2 2 ip addresses to compare
 *
 *  @return  true if that matches or else false
 *
 *  @pre     (ip_addr1 != NULL) && (ip_addr2 != NULL)
 *
 */

boolean util_compare_ip (cpr_ip_addr_t *ip_addr1, cpr_ip_addr_t *ip_addr2)
{
    if (ip_addr1->type != ip_addr2->type) {

        return(FALSE);
    }

    if (ip_addr1->type == CPR_IP_ADDR_IPV4 &&
        ip_addr2->type == CPR_IP_ADDR_IPV4) {

        return((boolean) (ip_addr1->u.ip4 == ip_addr2->u.ip4));

    } else if (ip_addr1->type == CPR_IP_ADDR_IPV6 &&
            ip_addr2->type == CPR_IP_ADDR_IPV6) {

        return((boolean)memcmp((void *)&(ip_addr1->u.ip6.addr.base8),
                    (void *)&(ip_addr2->u.ip6.addr.base8), 16));
    }

    return(FALSE);
}

/*
 *  Extract ip address information from socket storage structure
 *
 *  @param ip_addr  ip address to be filled.
 *          cpr_sockaddr_storage storage structure pointer
 *
 *  @return  none
 *
 *  @pre     (ip_addr != NULL)
 *
 */
void util_extract_ip (cpr_ip_addr_t *ip_addr,
                        cpr_sockaddr_storage *from)
{
    switch (from->ss_family) {
    case AF_INET6:
        ip_addr->type = CPR_IP_ADDR_IPV6;
        ip_addr->u.ip6 = ((cpr_sockaddr_in6_t *)from)->sin6_addr;
        break;
    case AF_INET:
        ip_addr->type = CPR_IP_ADDR_IPV4;
        ip_addr->u.ip4 = ((cpr_sockaddr_in_t *)from)->sin_addr.s_addr;
        break;
    default:
        break;
    }
}

/*
 *  Get port number from storage structure.
 *
 *  @param sock_storage
 *
 *  @return  port number
 *
 *  @pre     (sock_storage != NULL)
 *
 */

uint16_t util_get_port (cpr_sockaddr_storage *sock_storage)
{
    switch (sock_storage->ss_family) {
    case AF_INET6:
        return(((cpr_sockaddr_in6_t *)sock_storage)->sin6_port);
    case AF_INET:
        return(((cpr_sockaddr_in_t *)sock_storage)->sin_port);
    default:
        break;
    }
    return(0);
}

void util_get_ip_using_mode (cpr_ip_addr_t *ip_addr, cpr_ip_mode_e ip_mode,
                             uint32_t  ip4, char *ip6)
{
    *ip_addr = ip_addr_invalid;

    switch (ip_mode) {
    case CPR_IP_MODE_IPV4:
        ip_addr->type = CPR_IP_ADDR_IPV4;
        ip_addr->u.ip4 = ip4;
        break;
    case CPR_IP_MODE_IPV6:
        ip_addr->type = CPR_IP_ADDR_IPV6;
        if (ip6 != NULL) {
            memcpy((void *)&(ip_addr->u.ip6.addr.base8[16]), (void *)ip6, 16);
        }
        break;
    case CPR_IP_MODE_DUAL:
    default:
        break;
    }

}

unsigned long
gmt_string_to_seconds (char *gmt_string, unsigned long *seconds)
{
    char *token;

    // Do a preliminary check and see if the string
    // passed in is a completely numeric string
    // If it is, then we will return just that number
    // and return a 1 for the error code, meaning
    // we parsed a
    *seconds = strtoul(gmt_string, &token, 10);
    if ((token == NULL) || (token[0] == '\0')) {
        return 1;
    }
    *seconds = 0;
    return 0;
}

long
diff_current_time (unsigned long t1, unsigned long *difference)
{
    *difference = 1;
    return 0;
}

boolean
is_empty_str (char *str)
{
    if (str == NULL) {
        return TRUE;
    }
    if (strncmp(str, EMPTY_STR, EMPTY_STR_LEN) == 0) {
        return TRUE;
    }
    return FALSE;
}

void
init_empty_str (char *str)
{
    strcpy(str,EMPTY_STR);
}