original files of m241
This commit is contained in:
@@ -0,0 +1,588 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipike_dynamic_ip.c,v $ $Revision: 1.23.10.7 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipike/src/ipike_dynamic_ip.c,v $
|
||||
* $Author: zan $ $Date: 2013-08-08 09:53:45 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipike_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipike_h.h"
|
||||
#include "ipike.h"
|
||||
#include "ipike_util.h"
|
||||
#include "ipike_dynamic_ip.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_initiate_address_reference
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipike_initiate_address_reference(
|
||||
const char *id,
|
||||
const char *ifname,
|
||||
union Ip_sockaddr_union *addr,
|
||||
union Ip_sockaddr_union *netmask)
|
||||
{
|
||||
char entry[64] = {0};
|
||||
char value[16] = {0};
|
||||
const char* name = IP_NULL;
|
||||
int count = 0;
|
||||
|
||||
/* Format:
|
||||
*
|
||||
* ipike.added_addresses.id.<id>=<addr>
|
||||
* ipike.added_addresses.<addr>.id=<id>
|
||||
* ipike.added_addresses.<addr>.interface=<ifname>
|
||||
* ipike.added_addresses.<addr>.count=0
|
||||
* ipike.added_addresses.<addr>.netmask=<netmask>
|
||||
*/
|
||||
name = ipike_addr_to_str(addr);
|
||||
if (name==IP_NULL)
|
||||
return IP_NULL;
|
||||
if (ipcom_strlen(name) < (sizeof(entry)-32))
|
||||
{
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.id.%s", id);
|
||||
(void)ipcom_sysvar_set(entry, name, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.id", name);
|
||||
(void)ipcom_sysvar_set(entry, id, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.interface", name);
|
||||
(void)ipcom_sysvar_set(entry, ifname, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.count", name);
|
||||
/* Read old if renew got same address */
|
||||
count = ipcom_sysvar_get_as_int(entry, 0);
|
||||
ipcom_sprintf(value, "%d", count);
|
||||
(void)ipcom_sysvar_set(entry, value, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.netmask", name);
|
||||
name = ipike_addr_to_str(netmask);
|
||||
if (name != IP_NULL)
|
||||
(void)ipcom_sysvar_set(entry, name, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_has_valid_address_reference
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_bool
|
||||
ipike_has_valid_address_reference(const char *id)
|
||||
{
|
||||
Ip_bool has = IP_FALSE;
|
||||
char entry[64] = {0};
|
||||
char value[64] = {0};
|
||||
Ip_size_t len = 0;
|
||||
union Ip_sockaddr_union addr;
|
||||
|
||||
if (ipcom_strlen(id) < (sizeof(entry)-25))
|
||||
{
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.id.%s", id);
|
||||
len = sizeof(value);
|
||||
if ( ipcom_sysvar_get(entry, value, &len) != IP_NULL && value[0] != 0 )
|
||||
{
|
||||
if ( ipike_addr_set(&addr,value) != IPIKE_SUCCESS ||
|
||||
ipike_addr_is_zero(&addr))
|
||||
{
|
||||
IPCOM_LOG0(DEBUG, "ipike_has_valid_address_reference: bad address");
|
||||
(void)ipcom_sysvar_unset(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG1(DEBUG2, "ipike_has_valid_address_reference: got address %s", value);
|
||||
has = IP_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return has;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_remove_address_reference
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipike_remove_address_reference(const char *id)
|
||||
{
|
||||
char entry[64] = {0};
|
||||
|
||||
if (ipcom_strlen(id) < (sizeof(entry)-25))
|
||||
{
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.id.%s", id);
|
||||
(void)ipcom_sysvar_unset(entry);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_increase_address_reference
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipike_increase_address_reference(union Ip_sockaddr_union *addr)
|
||||
{
|
||||
char entry[64] = {0};
|
||||
char value[64] = {0};
|
||||
const char* name = IP_NULL;
|
||||
Ip_size_t len = 0;
|
||||
int count = 0;
|
||||
union Ip_sockaddr_union netmask;
|
||||
|
||||
name = ipike_addr_to_str(addr);
|
||||
if (name==IP_NULL)
|
||||
return;
|
||||
if (ipcom_strlen(name) < (sizeof(entry)-32))
|
||||
{
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.count", name);
|
||||
count = ipcom_sysvar_get_as_int(entry, 0);
|
||||
count++;
|
||||
ipcom_sprintf(value, "%d", count);
|
||||
(void)ipcom_sysvar_set(entry, value, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
if (count == 1)
|
||||
{
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.netmask", name);
|
||||
len = sizeof(value);
|
||||
if (((ipcom_sysvar_get(entry, value, &len)) != IP_NULL) &&
|
||||
(value[0] != 0))
|
||||
{
|
||||
(void)ipike_addr_set(&netmask,value);
|
||||
}
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.interface", name);
|
||||
len = sizeof(value);
|
||||
if (((ipcom_sysvar_get(entry, value, &len)) == IP_NULL) ||
|
||||
(value[0] == 0) ||
|
||||
ipike_add_delete_address(IP_TRUE, value, addr, &netmask))
|
||||
{
|
||||
IPCOM_LOG0(DEBUG, "ipike_increase_address_reference: failed to add address");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_decrease_address_reference
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipike_decrease_address_reference(union Ip_sockaddr_union *addr)
|
||||
{
|
||||
char entry[64] = {0};
|
||||
char value[64] = {0};
|
||||
const char* id = IP_NULL;
|
||||
const char* name = IP_NULL;
|
||||
int count = 0;
|
||||
Ip_size_t len = 0;
|
||||
|
||||
name = ipike_addr_to_str(addr);
|
||||
if (name==IP_NULL)
|
||||
return;
|
||||
if (ipcom_strlen(name) < (sizeof(entry)-32))
|
||||
{
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.count", name);
|
||||
count = ipcom_sysvar_get_as_int(entry, 0);
|
||||
if (count == 1)
|
||||
{
|
||||
/* Do cleanup and delete dynamic ip address */
|
||||
(void)ipcom_sysvar_unset(entry);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.id", name);
|
||||
len = sizeof(value);
|
||||
id = ipcom_sysvar_get(entry, value, &len);
|
||||
(void)ipcom_sysvar_unset(entry);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.id.%s", id);
|
||||
(void)ipcom_sysvar_unset(entry);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.netmask", name);
|
||||
(void)ipcom_sysvar_unset(entry);
|
||||
ipcom_sprintf(entry, "ipike.added_addresses.%s.interface", name);
|
||||
len = sizeof(value);
|
||||
name = ipcom_sysvar_get(entry, value, &len);
|
||||
(void)ipcom_sysvar_unset(entry);
|
||||
if (ipike_add_delete_address(IP_FALSE, name, addr, IP_NULL))
|
||||
{
|
||||
IPCOM_LOG0(DEBUG, "ipike_decrease_address_reference: failed to delete address");
|
||||
}
|
||||
}
|
||||
else if (count > 1)
|
||||
{
|
||||
count--;
|
||||
ipcom_sprintf(value, "%d", count);
|
||||
(void)ipcom_sysvar_set(entry, value, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_update_interface_addresses
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_update_interface_addresses(
|
||||
const char *id,
|
||||
const char *ifname,
|
||||
union Ip_sockaddr_union *addr,
|
||||
union Ip_sockaddr_union *netmask,
|
||||
union Ip_sockaddr_union **dns,
|
||||
union Ip_sockaddr_union **nbns)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
const char *str = IP_NULL;
|
||||
|
||||
(void)nbns; /* not supported */
|
||||
|
||||
/* Set dns server if specified */
|
||||
if (dns != IP_NULL)
|
||||
{
|
||||
if (dns[0] != IP_NULL)
|
||||
{
|
||||
if (dns[0]->sa.sa_family != 0)
|
||||
{
|
||||
str = ipike_addr_to_str(dns[0]);
|
||||
if (ipcom_sysvar_set("ipdnsc.primaryns", str, IPCOM_SYSVAR_FLAG_OVERWRITE))
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
if ( dns[1] != IP_NULL && err == IPIKE_SUCCESS )
|
||||
{
|
||||
if (dns[1]->sa.sa_family != 0)
|
||||
{
|
||||
str = ipike_addr_to_str(dns[1]);
|
||||
if (ipcom_sysvar_set("ipdnsc.secondaryns", str, IPCOM_SYSVAR_FLAG_OVERWRITE))
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Initiate the reference counter for ip address */
|
||||
if (err == IPIKE_SUCCESS)
|
||||
ipike_initiate_address_reference(id, ifname, addr, netmask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_get_interface_addresses
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_get_interface_addresses(
|
||||
Ip_bool ip4,
|
||||
Ipike_value *peer_id,
|
||||
Ip_u32 counter,
|
||||
union Ip_sockaddr_union *addr,
|
||||
union Ip_sockaddr_union *netmask,
|
||||
union Ip_sockaddr_union ***dns,
|
||||
union Ip_sockaddr_union ***nbns)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
char *name = IP_NULL;
|
||||
char str[128] = {0};
|
||||
Ip_size_t len = 0;
|
||||
Ip_u32 n = 0;
|
||||
char **vec = IP_NULL;
|
||||
union Ip_sockaddr_union *tmp = IP_NULL;
|
||||
char *addrstr = IP_NULL;
|
||||
|
||||
/* This is a sample implementation to get dynamic addresses. This
|
||||
* implementation only support IPv4 and does not support multiple
|
||||
* addresses and expire (infinite). */
|
||||
if (!ip4)
|
||||
{
|
||||
#ifdef IPCOM_USE_INET6
|
||||
char *prefixptr = IP_NULL;
|
||||
int n1;
|
||||
int prefixlen = 128;
|
||||
|
||||
name = (char*)ipcom_malloc(peer_id->len*2+1+28+4);
|
||||
if (name == IP_NULL)
|
||||
{
|
||||
IP_PANIC();
|
||||
err = IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_strcpy(name, "ipike.address_pool.used.ip6.");
|
||||
ipike_bin2hex(peer_id->value, peer_id->len, &name[ipcom_strlen(name)]);
|
||||
ipcom_sprintf(&name[ipcom_strlen(name)], "%.2x", (Ip_u16)counter);
|
||||
/* Possible to reuse old? */
|
||||
len = sizeof(str);
|
||||
if ((ipcom_sysvar_get(name, str, &len) == IP_NULL) ||
|
||||
(ipike_addr_load_subnet(str, addr, netmask) != IPIKE_SUCCESS))
|
||||
{
|
||||
/* Allocate new */
|
||||
len = sizeof(str);
|
||||
|
||||
if (ipcom_sysvar_get("ipike.address_pool.network6", str, &len) == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Dynamic address: No pool available, set sysvar ipike.address_pool.network6");
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
|
||||
/* Find prefix len before all processing if configured*/
|
||||
if (IP_NULL != (prefixptr = ipcom_strchr(str, '/')))
|
||||
{
|
||||
n1 = atoi(prefixptr+1);
|
||||
if( (n1 / 8) > 16)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "Dynamic address: Invalid pool: bad netmask (%d)", n1);
|
||||
}
|
||||
prefixlen = n1;
|
||||
}
|
||||
|
||||
if ( (err == IPIKE_SUCCESS) &&
|
||||
( (ipike_addr_load_subnet(str, addr, netmask) != IPIKE_SUCCESS) ||
|
||||
(ipcom_sysvar_set(name, str, IPCOM_SYSVAR_FLAG_OVERWRITE) != IPCOM_SUCCESS)
|
||||
)
|
||||
)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Dynamic address: Invalid pool, check sysvar ipike.address_pool.network6");
|
||||
err = IPIKE_FAILED;
|
||||
|
||||
}
|
||||
|
||||
if (err == IPIKE_SUCCESS)
|
||||
{
|
||||
if ( (err = ipike_addr_increment_v6(addr, prefixlen) != IPIKE_SUCCESS) )
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Dynamic address: Failed to increment IPv6 address");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
addrstr=ipike_addr_subnet_to_str(addr, netmask);
|
||||
if (addrstr==IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to update dynamic address pool");
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_strncpy(str, addrstr,127);
|
||||
|
||||
if (ipcom_sysvar_set("ipike.address_pool.network6", str, IPCOM_SYSVAR_FLAG_OVERWRITE))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Dynamic address: Failed to update dynamic address pool");
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef IPCOM_USE_INET
|
||||
name = (char*)ipcom_malloc(peer_id->len*2+1+28+4);
|
||||
if (name == IP_NULL)
|
||||
{
|
||||
IP_PANIC();
|
||||
err = IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_strcpy(name, "ipike.address_pool.used.ip4.");
|
||||
ipike_bin2hex(peer_id->value, peer_id->len, &name[ipcom_strlen(name)]);
|
||||
ipcom_sprintf(&name[ipcom_strlen(name)], "%.2x", (Ip_u16)counter);
|
||||
/* Possible to reuse old? */
|
||||
len = sizeof(str);
|
||||
if ((ipcom_sysvar_get(name, str, &len) == IP_NULL) ||
|
||||
(ipike_addr_load_subnet(str, addr, netmask) != IPIKE_SUCCESS))
|
||||
{
|
||||
/* Allocate new */
|
||||
len = sizeof(str);
|
||||
if ((ipcom_sysvar_get("ipike.address_pool.network4", str, &len) == IP_NULL) ||
|
||||
(ipike_addr_load_subnet(str, addr, netmask) != IPIKE_SUCCESS) ||
|
||||
(ipcom_sysvar_set(name, str, IPCOM_SYSVAR_FLAG_OVERWRITE) != IPCOM_SUCCESS))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "No dynamic address pool available, set sysvar ipike.address_pool.network4");
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = addr->sin.sin_addr.s_addr;
|
||||
addr->sin.sin_addr.s_addr = ip_ntohl(addr->sin.sin_addr.s_addr);
|
||||
if ((++addr->sin.sin_addr.s_addr & 0xff) == 0)
|
||||
addr->sin.sin_addr.s_addr++;
|
||||
addr->sin.sin_addr.s_addr = ip_htonl(addr->sin.sin_addr.s_addr);
|
||||
addrstr=ipike_addr_subnet_to_str(addr, netmask);
|
||||
|
||||
if (addrstr==IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to update dynamic address pool");
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_strncpy(str, addrstr,127);
|
||||
if (ipcom_sysvar_set("ipike.address_pool.network4", str, IPCOM_SYSVAR_FLAG_OVERWRITE))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to update dynamic address pool");
|
||||
err = IPIKE_FAILED;
|
||||
}
|
||||
}
|
||||
addr->sin.sin_addr.s_addr = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((IPIKE_SUCCESS == err) && (IP_NULL != dns))
|
||||
{
|
||||
len = sizeof(str);
|
||||
if (ipcom_sysvar_get("ipike.address_pool.dns4", str, &len) != IP_NULL)
|
||||
{
|
||||
if (IP_NULL == (vec = ipike_strvec(str, ", ")))
|
||||
{
|
||||
IP_PANIC();
|
||||
err = IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
while ((err == IPIKE_SUCCESS) && (vec[n] != IP_NULL))
|
||||
{
|
||||
if (IP_NULL == (tmp = ipcom_calloc(1, sizeof(*tmp))))
|
||||
{
|
||||
IP_PANIC();
|
||||
err = IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ipike_addr_set(tmp, vec[n]);
|
||||
if (err == IPIKE_SUCCESS)
|
||||
err = ipike_array_add((void***)dns, tmp);
|
||||
if (err != IPIKE_SUCCESS)
|
||||
ipcom_free(tmp);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
ipike_array_free((void**)vec, ipcom_free);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((IPIKE_SUCCESS == err) && (IP_NULL != nbns))
|
||||
{
|
||||
len = sizeof(str);
|
||||
if (ipcom_sysvar_get("ipike.address_pool.nbns4", str, &len) != IP_NULL)
|
||||
{
|
||||
if (IP_NULL == (vec = ipike_strvec(str, ", ")))
|
||||
{
|
||||
IP_PANIC();
|
||||
err = IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
while ((err == IPIKE_SUCCESS) && (vec[n] != IP_NULL))
|
||||
{
|
||||
if (IP_NULL == (tmp = ipcom_calloc(1, sizeof(*tmp))))
|
||||
{
|
||||
IP_PANIC();
|
||||
err = IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = ipike_addr_set(tmp, vec[n]);
|
||||
if (err == IPIKE_SUCCESS)
|
||||
err = ipike_array_add((void***)nbns, tmp);
|
||||
if (err != IPIKE_SUCCESS)
|
||||
ipcom_free(tmp);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
ipike_array_free((void**)vec, ipcom_free);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( name != IP_NULL )
|
||||
ipcom_free(name);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user