This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/509-remove-cpputests in repository https://gitbox.apache.org/repos/asf/celix.git
commit b4b26a3f7e06d3037e8399ceb09903e6a17b70ab Author: Pepijn Noltes <[email protected]> AuthorDate: Thu Jan 4 14:16:12 2024 +0100 Remove ip utils --- CHANGES.md | 2 +- libs/utils/CMakeLists.txt | 1 - libs/utils/gtest/CMakeLists.txt | 2 - .../gtest/src/IpUtilsErrorInjectionTestSuite.cc | 83 -------- libs/utils/gtest/src/IpUtilsTestSuite.cc | 127 ------------ libs/utils/include/celix_ip_utils.h | 117 ----------- libs/utils/src/ip_utils.c | 222 --------------------- 7 files changed, 1 insertion(+), 553 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 157978a4..12ddff48 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -55,7 +55,7 @@ limitations under the License. THe celix_status_t is used to indicate an ENOMEM error. - Embedded bundles are no longer supported. - linked_list.h is removed and no longer supported. Use celix_array_list.h instead. -- IP utils is refactored and the API is changed and all IP utils functions are now prefixed with `celix_utils_`. +- ip_utils.h is removed and no longer supported. - array_list.h is removed and no longer supported. Use celix_array_list.h instead. ## New Features diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index a9b31234..0f4dd641 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -38,7 +38,6 @@ if (UTILS) src/version_range.c src/properties.c src/utils.c - src/ip_utils.c src/filter.c src/celix_log_level.c src/celix_log_utils.c diff --git a/libs/utils/gtest/CMakeLists.txt b/libs/utils/gtest/CMakeLists.txt index 012d2cd3..e1e22ef7 100644 --- a/libs/utils/gtest/CMakeLists.txt +++ b/libs/utils/gtest/CMakeLists.txt @@ -34,7 +34,6 @@ add_executable(test_utils src/ThreadsTestSuite.cc src/CelixErrnoTestSuite.cc src/CelixUtilsAutoCleanupTestSuite.cc - src/IpUtilsTestSuite.cc src/DeprecatedHashmapTestSuite.cc ) @@ -108,7 +107,6 @@ if (EI_TESTS) add_executable(test_utils_with_ei src/FileUtilsErrorInjectionTestSuite.cc src/ConvertUtilsErrorInjectionTestSuite.cc - src/IpUtilsErrorInjectionTestSuite.cc src/ArrayListErrorInjectionTestSuite.cc src/PropertiesErrorInjectionTestSuite.cc src/VersionErrorInjectionTestSuite.cc diff --git a/libs/utils/gtest/src/IpUtilsErrorInjectionTestSuite.cc b/libs/utils/gtest/src/IpUtilsErrorInjectionTestSuite.cc deleted file mode 100644 index 9f0dce5b..00000000 --- a/libs/utils/gtest/src/IpUtilsErrorInjectionTestSuite.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. - */ - -#include <gtest/gtest.h> - -#include "celix_ip_utils.h" -#include "celix_err.h" - -#include "celix_utils_ei.h" -#include "ifaddrs_ei.h" -#include "malloc_ei.h" - -class IpUtilsWithErrorInjectionTestSuite : public ::testing::Test { -public: - IpUtilsWithErrorInjectionTestSuite() { - celix_err_resetErrors(); - } - - ~IpUtilsWithErrorInjectionTestSuite() override { - celix_ei_expect_getifaddrs(nullptr, 0, 0); - celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); - celix_ei_expect_calloc(nullptr, 0, nullptr); - celix_err_resetErrors(); - } -}; - -TEST_F(IpUtilsWithErrorInjectionTestSuite, FailToGetInterfaceAddressesTest) { - celix_ei_expect_getifaddrs((void *)&celix_utils_findIpInSubnet, 0, -1); - char* ipAddr = nullptr; - auto status = celix_utils_findIpInSubnet("192.168.1.0/24", &ipAddr); - EXPECT_EQ(EMFILE, status); - EXPECT_EQ(ipAddr, nullptr); - EXPECT_EQ(1, celix_err_getErrorCount()); -} - -TEST_F(IpUtilsWithErrorInjectionTestSuite, FailToDuplicateStringTest) { - int errCount = 1; - char* ipAddr = nullptr; - - //first call to celix_utils_strdup fails - celix_ei_expect_celix_utils_strdup((void*)celix_utils_findIpInSubnet, 0, nullptr); - auto status = celix_utils_findIpInSubnet("192.168.1.0/24", &ipAddr); - EXPECT_EQ(status, ENOMEM); - EXPECT_EQ(ipAddr, nullptr); - EXPECT_EQ(errCount++, celix_err_getErrorCount()); - - //second call to celix_utils_strdup fails (in ifa -> ifa_next loop) - celix_ei_expect_celix_utils_strdup((void*)celix_utils_findIpInSubnet, 0, nullptr, 2); - status = celix_utils_findIpInSubnet("127.0.0.1/24", &ipAddr); - EXPECT_EQ(status, ENOMEM); - EXPECT_EQ(ipAddr, nullptr); - EXPECT_EQ(errCount++, celix_err_getErrorCount()); - - celix_ei_expect_celix_utils_strdup((void*)celix_utils_convertIpToUint, 0, nullptr); - bool converted; - auto ipAsUint = celix_utils_convertIpToUint("192.168.1.0", &converted); - EXPECT_EQ(ipAsUint, 0); - EXPECT_FALSE(converted); - EXPECT_EQ(errCount++, celix_err_getErrorCount()); -} - -TEST_F(IpUtilsWithErrorInjectionTestSuite, FailToCalledTest) { - celix_ei_expect_calloc((void*)celix_utils_convertUintToIp, 0, nullptr); - auto ip = celix_utils_convertUintToIp(3232235840); - EXPECT_EQ(ip, nullptr); - EXPECT_EQ(1, celix_err_getErrorCount()); -} diff --git a/libs/utils/gtest/src/IpUtilsTestSuite.cc b/libs/utils/gtest/src/IpUtilsTestSuite.cc deleted file mode 100644 index 27b5933e..00000000 --- a/libs/utils/gtest/src/IpUtilsTestSuite.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include <gtest/gtest.h> - -#include "celix_err.h" -#include "celix_ip_utils.h" -#include "celix_stdlib_cleanup.h" - -class IpUtilsTestSuite : public ::testing::Test { -public: - IpUtilsTestSuite() { - celix_err_resetErrors(); - } - ~IpUtilsTestSuite() override { - celix_err_printErrors(stderr, nullptr, nullptr); - } -}; - -TEST_F(IpUtilsTestSuite, ipToUnsignedIntTest) { - const char *ip = "192.168.1.64"; - uint32_t expected = 3232235840; - uint32_t actual = celix_utils_convertIpToUint(ip, nullptr); - EXPECT_EQ(expected, actual); - - bool converted; - actual = celix_utils_convertIpToUint(ip, &converted); - EXPECT_TRUE(converted); - EXPECT_EQ(expected, actual); - - EXPECT_EQ(0, celix_utils_convertIpToUint("a.b.c.d", &converted)); - EXPECT_FALSE(converted); - EXPECT_EQ(1, celix_err_getErrorCount()); - - EXPECT_EQ(0, celix_utils_convertIpToUint("273.168.1.64", &converted)); - EXPECT_FALSE(converted); - EXPECT_EQ(2, celix_err_getErrorCount()); - - EXPECT_EQ(0, celix_utils_convertIpToUint("10.1.1.1.1", &converted)); - EXPECT_FALSE(converted); - EXPECT_EQ(3, celix_err_getErrorCount()); -} - -TEST_F(IpUtilsTestSuite, unsignedIntToIpTest) { - uint32_t ipAsUint = 3232235840; - const char *expected = "192.168.1.64"; - char* ip = celix_utils_convertUintToIp(ipAsUint); - EXPECT_STREQ(expected, ip); - free(ip); - - ip = celix_utils_convertUintToIp(0); - EXPECT_STREQ("0.0.0.0", ip); - free(ip); - - ip = celix_utils_convertUintToIp(UINT32_MAX); - EXPECT_STREQ("255.255.255.255", ip); - free(ip); -} - -TEST_F(IpUtilsTestSuite, prefixToBitmaskTest) { - uint32_t bitmask = celix_utils_ipPrefixLengthToBitmask(27); - EXPECT_EQ(4294967264, bitmask); - - bitmask = celix_utils_ipPrefixLengthToBitmask(0); - EXPECT_EQ(0, bitmask); - - bitmask = celix_utils_ipPrefixLengthToBitmask(32); - EXPECT_EQ(UINT32_MAX, bitmask); - - bitmask = celix_utils_ipPrefixLengthToBitmask(-1); - EXPECT_EQ(0, bitmask); - - bitmask = celix_utils_ipPrefixLengthToBitmask(33); - EXPECT_EQ(0, bitmask); -} - -TEST_F(IpUtilsTestSuite, NetmaskToPrefixTest) { - int prefix = celix_utils_ipNetmaskToPrefixLength("255.255.255.0"); - EXPECT_EQ(24, prefix); - - prefix = celix_utils_ipNetmaskToPrefixLength("0.0.0.0"); - EXPECT_EQ(0, prefix); - - prefix = celix_utils_ipNetmaskToPrefixLength("255.255.255.255"); - EXPECT_EQ(32, prefix); - - prefix = celix_utils_ipNetmaskToPrefixLength("255.0.0.0"); - EXPECT_EQ(8, prefix); - - EXPECT_EQ(-1, celix_utils_ipNetmaskToPrefixLength("a.b.c.d")); - EXPECT_EQ(1, celix_err_getErrorCount()); -} - -TEST_F(IpUtilsTestSuite, FindIpInSubnetWithInvalidInputTest) { - char* ipAddr = nullptr; - - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, celix_utils_findIpInSubnet("198.168.0.1", &ipAddr)); // missing subnet - EXPECT_EQ(1, celix_err_getErrorCount()); - - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, celix_utils_findIpInSubnet("198.168.0.1/abc", &ipAddr)); // invalid subnet - EXPECT_EQ(2, celix_err_getErrorCount()); - - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, celix_utils_findIpInSubnet("198.168.0.1/40", &ipAddr)); // out of range subnet - EXPECT_EQ(3, celix_err_getErrorCount()); - - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, celix_utils_findIpInSubnet("198.168.0.1/-1", &ipAddr)); // out of range subnet - EXPECT_EQ(4, celix_err_getErrorCount()); - - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, celix_utils_findIpInSubnet("a.b.c.d/8", &ipAddr)); // invalid ip - EXPECT_EQ(5, celix_err_getErrorCount()); -} diff --git a/libs/utils/include/celix_ip_utils.h b/libs/utils/include/celix_ip_utils.h deleted file mode 100644 index 6ad89f07..00000000 --- a/libs/utils/include/celix_ip_utils.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * @file celix_ip_utils.h - * @brief Utility functions for IP address manipulation. - * - * This header file contains declarations of utility functions for - * converting IP addresses and manipulating IP address data. - */ - -#ifndef CELIX_IP_UTILS_H -#define CELIX_IP_UTILS_H - -#include "celix_errno.h" -#include "celix_utils_export.h" - -#include <stdbool.h> -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Converts an IP address in string format to an unsigned integer. - * - * This function takes an IP address as a string and converts it to - * its corresponding unsigned integer representation. - * - * If the conversation failed, an error message is logged to celix_err. - * - * @param[in] ip The IP address in string format (e.g., "192.168.0.1"). - * @param[out] converted A boolean indicating whether the conversion was successful. Can be NULL. - * @return The IP address as an uint32_t. Returns 0 if the conversion fails. - */ -uint32_t celix_utils_convertIpToUint(const char* ip, bool* converted); - -/** - * @brief Converts an unsigned integer to its corresponding IP address in string format. - * - * This function converts an unsigned integer representing an IP address - * to a string format. - * - * @param[in] ip The IP address as an uint32_t. - * @return The IP address in string format (e.g., "192.168.0.1"). - */ -char* celix_utils_convertUintToIp(uint32_t ip); - -/** - * @brief Converts a subnet prefix length to a bitmask. - * - * This function takes a subnet prefix length and converts it into - * a bitmask in unsigned integer format. - * - * @param[in] prefix The subnet prefix length. - * @return The corresponding bitmask as an unsigned integer. Returns 0 if the prefix is invalid or 0. - */ -uint32_t celix_utils_ipPrefixLengthToBitmask(int prefix); - -/** - * @brief Converts a netmask string to a prefix length. - * - * This function converts a netmask in string format (e.g., "255.255.255.0") - * to its corresponding prefix length. - * - * If the conversation failed, an error message is logged to celix_err. - * - * @param[in] netmask The netmask in string format. - * @return The prefix length or -1 if the conversion fails. - */ -int celix_utils_ipNetmaskToPrefixLength(const char* netmask); - -/** - * @brief Finds an IP address within a given subnet on the host's network interfaces. - * - * This function searches through the network interfaces of the host to find - * an IP address that falls within the specified subnet. It analyzes the IP addresses - * assigned to each network interface and checks if any of them match the given subnet criteria. - * The function returns the first IP address that is within the specified subnet range. - * - * The input parameter is expected to be in CIDR notation. - * CIDR notation is a concise format for specifying IP addresses ranges using IP address and subnet prefix length. - * It takes the form of 'IP_ADDRESS/PREFIX_LENGTH' (e.g., "192.168.0.1/24"). - * - * If an error occurred, an error message is logged to celix_err. - * - * @param[in] subnetCidrNotation The IP address with subnet prefix. - * @param[out] foundIp A string containing an IP address within the specified subnet that is also - * assigned to a network interface on the host, or NULL if no matching IP address is found. The caller is owner of the - * returned string. - * @return CELIX_SUCCESS if the IP address was found, CELIX_ILLEGAL_ARGUMENT if the subnet is invalid, CELIX_ENOMEM if - * an error occurred or a errno value set by getifaddrs. - */ -celix_status_t celix_utils_findIpInSubnet(const char* subnetCidrNotation, char** foundIp); - -#ifdef __cplusplus -} -#endif - -#endif /* CELIX_IP_UTILS_H */ diff --git a/libs/utils/src/ip_utils.c b/libs/utils/src/ip_utils.c deleted file mode 100644 index 8d5e0df4..00000000 --- a/libs/utils/src/ip_utils.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include "celix_ip_utils.h" - -#include "celix_err.h" -#include "celix_stdlib_cleanup.h" -#include "celix_utils.h" -#include "celix_convert_utils.h" - -#include <arpa/inet.h> -#include <assert.h> -#include <errno.h> -#include <ifaddrs.h> -#include <limits.h> -#include <math.h> -#include <netdb.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> - -uint32_t celix_utils_convertIpToUint(const char* ip, bool* converted) { - if (converted) { - *converted = false; - } - - // copy for strtok_r - celix_autofree char* input = celix_utils_strdup(ip); - if (!input) { - celix_err_push("Failed to duplicate input string for IP conversion"); - return 0; - } - - uint32_t ipAsUint = 0; - char* partOfIp = NULL; - char* savePtr = NULL; - int count = 0; - while ((partOfIp = strtok_r(partOfIp == NULL ? input : NULL, ".\0", &savePtr)) != NULL) { - if (count > 3) { - celix_err_pushf("Failed to convert IP address %s to unsigned int, to many parts", ip); - return 0; - } - bool longConverted = false; - long partAsLong = celix_utils_convertStringToLong(partOfIp, ULONG_MAX, &longConverted); - if (!longConverted) { - celix_err_pushf("Failed to convert IP address %s to unsigned int, part `%s` is not a number", ip, partOfIp); - return 0; - } else if (partAsLong > 255 || partAsLong < 0) { - celix_err_pushf("Failed to convert IP address %s to unsigned int, part `%s` is out of range", ip, partOfIp); - return 0; - } - ipAsUint += (uint32_t)(partAsLong * powl(256, 3 - count++)); - } - - if (converted) { - *converted = true; - } - return ipAsUint; -} - -char* celix_utils_convertUintToIp(uint32_t ip) { - char* ipStr = calloc(16, sizeof(char)); - if (!ipStr) { - celix_err_push("Failed to allocate memory for IP address string"); - return NULL; - } - - int64_t ipPart1 = ip / (int64_t)pow(256, 3); - ip -= ipPart1 * (int64_t)pow(256, 3); - int64_t ipPart2 = ip / (int64_t)pow(256, 2); - ip -= ipPart2 * (int64_t)pow(256, 2); - int64_t ipPart3 = ip / (int64_t)pow(256, 1); - ip -= ipPart3 * (int64_t)pow(256, 1); - int64_t ipPart4 = ip / (int64_t)pow(256, 0); - - snprintf(ipStr, 16, "%i.%i.%i.%i", (int)ipPart1, (int)ipPart2, (int)ipPart3, (int)ipPart4); - - return ipStr; -} - -uint32_t celix_utils_ipPrefixLengthToBitmask(int prefix) { - if (prefix > 32 || prefix <= 0) { - return 0; - } - return (uint32_t )((0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF); -} - -int celix_utils_ipNetmaskToPrefixLength(const char* netmask) { - // Convert netmask to in_addr object - struct in_addr in; - int ret = inet_pton(AF_INET, netmask, &in); - if (ret != 1) { - celix_err_pushf("Failed to convert netmask %s to in_addr object", netmask); - return -1; - } - - // Now convert the mask to a prefix - int prefix = 0; - uint32_t i = ntohl(in.s_addr); - - while (i > 0) { - if (i & 1) { - prefix++; - } - i >>= 1; - } - - return prefix; -} - -celix_status_t celix_utils_findIpInSubnet(const char* subnetCidrNotation, char** foundIp) { - assert(subnetCidrNotation); - assert(foundIp); - - *foundIp = NULL; - - //create copy for strtok_r - celix_autofree char* input = celix_utils_strdup(subnetCidrNotation); - if (!input) { - celix_err_push("Failed to duplicate input string for subnet search"); - return CELIX_ENOMEM; - } - - char* savePtr; - char* inputIp = strtok_r(input, "/", &savePtr); - char* inputPrefixStr = strtok_r(NULL, "\0", &savePtr); - - if (!inputPrefixStr) { - celix_err_pushf("Failed to parse IP address with prefix %s. Missing a '/'", subnetCidrNotation); - return CELIX_ILLEGAL_ARGUMENT; - } - - bool convertedLong = false; - int inputPrefix = (int)celix_utils_convertStringToLong(inputPrefixStr, INT_MAX, &convertedLong); - if (!convertedLong) { - celix_err_pushf("Failed to parse prefix in IP address with prefix %s", subnetCidrNotation); - return CELIX_ILLEGAL_ARGUMENT; - } else if (inputPrefix > 32 || inputPrefix < 0) { - celix_err_pushf( - "Failed to parse IP address with prefix %s. Prefix %s is out of range", subnetCidrNotation, inputPrefixStr); - return CELIX_ILLEGAL_ARGUMENT; - } - - bool converted; - uint32_t ipAsUint = celix_utils_convertIpToUint(inputIp, &converted); - if (!converted) { - return CELIX_ILLEGAL_ARGUMENT; - } - uint32_t bitmask = celix_utils_ipPrefixLengthToBitmask(inputPrefix); - - unsigned int ipRangeStart = ipAsUint & bitmask; - unsigned int ipRangeStop = ipAsUint | ~bitmask; - - // Requested IP range is known now, now loop through network interfaces - struct ifaddrs *ifap, *ifa; - - if (getifaddrs(&ifap) == -1) { - celix_status_t status = errno; - celix_err_push("Failed to get network interfaces"); - return status; - } - - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL) { - continue; - } - - if (ifa->ifa_addr->sa_family != AF_INET) { - continue; - } - - // Retrieve IP address for interface - char if_addr[NI_MAXHOST]; - int rv = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), if_addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - - if (rv != 0) { - celix_err_pushf("Failed to get IP address for interface %s: %s", ifa->ifa_name, gai_strerror(rv)); - continue; - } - - // Retrieve netmask - struct sockaddr_in* sa = (struct sockaddr_in*)ifa->ifa_netmask; - char* if_netmask = inet_ntoa(sa->sin_addr); - - uint32_t ifIpAsUint = celix_utils_convertIpToUint(if_addr, NULL); - int ifPrefix = celix_utils_ipNetmaskToPrefixLength(if_netmask); - if (ifPrefix == -1) { - break; - } - - if (ifIpAsUint >= ipRangeStart && ifIpAsUint <= ipRangeStop && inputPrefix >= ifPrefix) { - char* ip = celix_utils_strdup(if_addr); - if (!ip) { - freeifaddrs(ifap); - celix_err_push("Failed to duplicate IP address"); - return CELIX_ENOMEM; - } - *foundIp = ip; - break; - } - } - freeifaddrs(ifap); - return CELIX_SUCCESS; -}
