mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-08 13:21:51 +00:00
367 lines
8.2 KiB
C
367 lines
8.2 KiB
C
/* 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);
|
|
}
|