From: Krzysztof Dynowski Date: Thu, 30 Jul 2015 12:04:25 +0000 (+0200) Subject: Support getting list of ip/mask for one interface, change netdev_set_ip* to netdev_ad... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=36dfc7551f4fca721d364638b1a6191908ce34dd;p=platform%2Fcore%2Fsecurity%2Fvasum.git Support getting list of ip/mask for one interface, change netdev_set_ip* to netdev_add_ip* [Feature] Get list of configured ip/mask for zone interface [Cause] Many ip/mask entries can be assigned to one interface [Solution] Implement generic method getting list of network addresses [Verification] Build, install, use vsm net-add-ip to add ips vsm net-list to get configured ips Change-Id: I8d4c1b59e03800aa513811992cc13e71df8d599e --- diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index e8922ee..86bc808 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -562,8 +562,6 @@ void netdev_list(const Args& argv) } else { VsmNetdev netdev = NULL; - in_addr ipv4; - in6_addr ipv6; char buf[INET_ADDRSTRLEN|INET6_ADDRSTRLEN]; CommandLineInterface::executeCallback(bind(vsm_lookup_netdev_by_name, _1, @@ -573,25 +571,21 @@ void netdev_list(const Args& argv) cout << netdevToString(netdev) << endl; vsm_netdev_free(netdev); - CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv4_addr, + VsmAddrList addrs = NULL; + CommandLineInterface::executeCallback(bind(vsm_netdev_get_ip_addr, _1, argv[1].c_str(), argv[2].c_str(), - &ipv4)); - if (inet_ntop(AF_INET, &ipv4, buf, INET_ADDRSTRLEN) == NULL) { - throw runtime_error("Wrong address received"); + &addrs)); + unsigned listsize = vsm_addrlist_size(addrs); + for (unsigned i=0; i < listsize; ++i) { + int type=vsm_addrlist_get_type(addrs, i); + if (inet_ntop(type, vsm_addrlist_get_addr(addrs, i), buf, INET6_ADDRSTRLEN) == NULL) { + throw runtime_error("Wrong address received ["+std::to_string(i)+"] type="+std::to_string(type)); + } + cout << buf << "/" << vsm_addrlist_get_prefix(addrs, i) << endl; } - cout << buf << endl; - - CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv6_addr, - _1, - argv[1].c_str(), - argv[2].c_str(), - &ipv6)); - if (inet_ntop(AF_INET6, &ipv6, buf, INET6_ADDRSTRLEN) == NULL) { - throw runtime_error("Wrong address received"); - } - cout << buf << endl; + vsm_addrlist_free(addrs); } } @@ -606,7 +600,7 @@ void netdev_add_ip_addr(const Args& argv) if (inet_pton(AF_INET, argv[3].c_str(), &addr) != 1) { throw runtime_error("Wrong address format"); }; - CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv4_addr, + CommandLineInterface::executeCallback(bind(vsm_netdev_add_ipv4_addr, _1, argv[1].c_str(), argv[2].c_str(), @@ -618,7 +612,7 @@ void netdev_add_ip_addr(const Args& argv) if (inet_pton(AF_INET6, argv[3].c_str(), &addr) != 1) { throw runtime_error("Wrong address format"); }; - CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv6_addr, + CommandLineInterface::executeCallback(bind(vsm_netdev_add_ipv6_addr, _1, argv[1].c_str(), argv[2].c_str(), diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 15cccf6..e3aca1d 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -525,42 +525,48 @@ VsmStatus Client::vsm_zone_get_netdevs(const char* id, VsmArrayString* netdevIds VsmStatus Client::vsm_netdev_get_ip_addr(const char* id, const char* netdevId, - int type, - void* addr) noexcept + std::vector& addrs) noexcept { using namespace boost::algorithm; return coverException([&] { IS_SET(id); IS_SET(netdevId); - IS_SET(addr); + + addrs.clear(); api::GetNetDevAttrs attrs = *mClient->callSync( api::ipc::METHOD_GET_NETDEV_ATTRS, std::make_shared(api::GetNetDevAttrsIn{ id, netdevId })); - auto it = find_if(attrs.values.begin(), - attrs.values.end(), - [type](const api::StringPair& entry) { - return entry.first == (type == AF_INET ? "ipv4" : "ipv6"); - }); + for (const auto &attr : attrs.values) { + InetAddr addr; + if (attr.first == "ipv4") { + addr.type = AF_INET; + } + else if (attr.first == "ipv6") { + addr.type = AF_INET6; + } + else continue; - if (it != attrs.values.end()) { - vector addrAttrs; - for(auto addrAttr : split(addrAttrs, it->second, is_any_of(","))) { + std::vector addrAttrs; + for(const auto& addrAttr : split(addrAttrs, attr.second, is_any_of(","))) { size_t pos = addrAttr.find(":"); - if (addrAttr.substr(0, pos) == "ip") { - if (pos != string::npos && pos < addrAttr.length() && - inet_pton(type, addrAttr.substr(pos + 1).c_str(), addr) == 1) { - //XXX: return only one address - return; - } else { - throw InvalidResponseException("Wrong address format returned"); + if (pos == string::npos) continue; + + if (addrAttr.substr(0, pos) == "prefixlen") { + addr.prefix = atoi(addrAttr.substr(pos + 1).c_str()); + } + else if (addrAttr.substr(0, pos) == "ip") { + if (inet_pton(addr.type, addrAttr.substr(pos + 1).c_str(), &addr.addr) != 1) { + addr.type = -1; + break; } } } + if (addr.type >= 0) + addrs.push_back(addr); } - throw OperationFailedException("Address not found"); }); } @@ -568,17 +574,33 @@ VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* id, const char* netdevId, struct in_addr* addr) noexcept { - return vsm_netdev_get_ip_addr(id, netdevId, AF_INET, addr); + std::vector addrs; + VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs); + for (const auto& a : addrs) { + if (a.type == AF_INET) { + memcpy(addr, &a.addr, sizeof(*addr)); + break; + } + } + return st; } VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* id, const char* netdevId, struct in6_addr* addr) noexcept { - return vsm_netdev_get_ip_addr(id, netdevId, AF_INET6, addr); + std::vector addrs; + VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs); + for (const auto& a : addrs) { + if (a.type == AF_INET6) { + memcpy(addr, &a.addr, sizeof(*addr)); + break; + } + } + return st; } -VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id, +VsmStatus Client::vsm_netdev_add_ipv4_addr(const char* id, const char* netdevId, struct in_addr* addr, int prefix) noexcept @@ -596,7 +618,7 @@ VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id, }); } -VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* id, +VsmStatus Client::vsm_netdev_add_ipv6_addr(const char* id, const char* netdevId, struct in6_addr* addr, int prefix) noexcept diff --git a/client/vasum-client-impl.hpp b/client/vasum-client-impl.hpp index 4297c95..dbc9001 100644 --- a/client/vasum-client-impl.hpp +++ b/client/vasum-client-impl.hpp @@ -64,6 +64,19 @@ typedef struct NetdevStructure { } *Netdev; /** + * Network interface information structure + */ +typedef struct { + int type; + int prefix; + union { + struct in_addr ipv4; + struct in6_addr ipv6; + } addr; +} InetAddr; + + +/** * vasum's client definition. * * Client uses dbus API. @@ -227,6 +240,10 @@ public: */ VsmStatus vsm_zone_get_netdevs(const char* zone, VsmArrayString* netdevIds) noexcept; + VsmStatus vsm_netdev_get_ip_addr(const char* zone, + const char* netdevId, + std::vector& addrs) noexcept; + /** * @see ::vsm_netdev_get_ipv4_addr */ @@ -242,17 +259,17 @@ public: struct in6_addr *addr) noexcept; /** - * @see ::vsm_netdev_set_ipv4_addr + * @see ::vsm_netdev_add_ipv4_addr */ - VsmStatus vsm_netdev_set_ipv4_addr(const char* zone, + VsmStatus vsm_netdev_add_ipv4_addr(const char* zone, const char* netdevId, struct in_addr *addr, int prefix) noexcept; /** - * @see ::vsm_netdev_set_ipv6_addr + * @see ::vsm_netdev_add_ipv6_addr */ - VsmStatus vsm_netdev_set_ipv6_addr(const char* zone, + VsmStatus vsm_netdev_add_ipv6_addr(const char* zone, const char* netdevId, struct in6_addr *addr, int prefix) noexcept; @@ -376,10 +393,6 @@ private: bool isInternalDispatcherEnabled() const; ipc::epoll::EventPoll& getEventPoll() const; VsmStatus coverException(const std::function& worker) noexcept; - VsmStatus vsm_netdev_get_ip_addr(const char* zone, - const char* netdevId, - int type, - void* addr) noexcept; }; #endif /* VASUM_CLIENT_IMPL_HPP */ diff --git a/client/vasum-client.cpp b/client/vasum-client.cpp index ee3e6d4..9cf15b3 100644 --- a/client/vasum-client.cpp +++ b/client/vasum-client.cpp @@ -279,6 +279,21 @@ API VsmStatus vsm_zone_get_netdevs(VsmClient client, return getClient(client).vsm_zone_get_netdevs(zone, netdevIds); } +API VsmStatus vsm_netdev_get_ip_addr(VsmClient client, + const char* zone, + const char* netdevId, + VsmAddrList *addrs) +{ + std::vector addrlist; + VsmStatus status = getClient(client).vsm_netdev_get_ip_addr(zone, netdevId, addrlist); + int n = addrlist.size(); + InetAddr *a = (InetAddr *)malloc((n+1)*sizeof(InetAddr)); + std::copy(addrlist.begin(), addrlist.end(), a); + a[n].type=-1; + *addrs = a; + return status; +} + API VsmStatus vsm_netdev_get_ipv4_addr(VsmClient client, const char* zone, const char* netdevId, @@ -295,22 +310,22 @@ API VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client, return getClient(client).vsm_netdev_get_ipv6_addr(zone, netdevId, addr); } -API VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client, +API VsmStatus vsm_netdev_add_ipv4_addr(VsmClient client, const char* zone, const char* netdevId, struct in_addr *addr, int prefix) { - return getClient(client).vsm_netdev_set_ipv4_addr(zone, netdevId, addr, prefix); + return getClient(client).vsm_netdev_add_ipv4_addr(zone, netdevId, addr, prefix); } -API VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client, +API VsmStatus vsm_netdev_add_ipv6_addr(VsmClient client, const char* zone, const char* netdevId, struct in6_addr *addr, int prefix) { - return getClient(client).vsm_netdev_set_ipv6_addr(zone, netdevId, addr, prefix); + return getClient(client).vsm_netdev_add_ipv6_addr(zone, netdevId, addr, prefix); } API VsmStatus vsm_netdev_del_ipv4_addr(VsmClient client, @@ -430,3 +445,29 @@ API VsmStatus vsm_clean_up_zones_root(VsmClient client) return getClient(client).vsm_clean_up_zones_root(); } +API unsigned int vsm_addrlist_size(VsmAddrList addrs) +{ + InetAddr *a = static_cast(addrs); + unsigned int i; + for (i = 0; a[i].type >= 0; ++i) ; + return i; +} + +API int vsm_addrlist_get_type(VsmAddrList addrs, unsigned int i) +{ + return static_cast(addrs)[i].type; +} + +API const void *vsm_addrlist_get_addr(VsmAddrList addrs, unsigned int i) +{ + return &static_cast(addrs)[i].addr; +} + +API unsigned int vsm_addrlist_get_prefix(VsmAddrList addrs, unsigned int i) +{ + return static_cast(addrs)[i].prefix; +} + +API void vsm_addrlist_free(VsmAddrList addrs) { + free(addrs); +} diff --git a/client/vasum-client.h b/client/vasum-client.h index b696dcf..253306d 100644 --- a/client/vasum-client.h +++ b/client/vasum-client.h @@ -186,6 +186,7 @@ typedef char* VsmString; */ typedef VsmString* VsmArrayString; +typedef void *VsmAddrList; /** * Completion status of libvasum-client's functions */ @@ -652,6 +653,29 @@ VsmStatus vsm_revoke_device(VsmClient client, const char* zone, const char* devi */ VsmStatus vsm_zone_get_netdevs(VsmClient client, const char* zone, VsmArrayString* netdevIds); + +/** + * Get ipv4 address for given netdevId + * + * @param[in] client vasum-server's client + * @param[in] zone zone name + * @param[in] netdevId netdev id + * @param[out] addrs ip address array + * @return status of this function call + * @remark Use vsm_netdev_addr_free() to free memory occupied by address array. + */ +VsmStatus vsm_netdev_get_ip_addr(VsmClient client, + const char* zone, + const char* netdevId, + VsmAddrList *addrs); + +/** + * Release VsmAddrList + * + * @param addrs VsmAddrList + */ +void vsm_addrlist_free(VsmAddrList addrs); + /** * Get ipv4 address for given netdevId * @@ -681,7 +705,7 @@ VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client, struct in6_addr *addr); /** - * Set ipv4 address for given netdevId + * Add ipv4 address for given netdevId * * @param[in] client vasum-server's client * @param[in] zone zone name @@ -690,14 +714,14 @@ VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client, * @param[in] prefix bit-length of the network prefix * @return status of this function call */ -VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client, +VsmStatus vsm_netdev_add_ipv4_addr(VsmClient client, const char* zone, const char* netdevId, struct in_addr *addr, int prefix); /** - * Set ipv6 address for given netdevId + * Add ipv6 address for given netdevId * * @param[in] client vasum-server's client * @param[in] zone zone name @@ -706,7 +730,7 @@ VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client, * @param[in] prefix bit-length of the network prefix * @return status of this function call */ -VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client, +VsmStatus vsm_netdev_add_ipv6_addr(VsmClient client, const char* zone, const char* netdevId, struct in6_addr *addr, @@ -933,6 +957,35 @@ VsmStatus vsm_remove_declaration(VsmClient client, */ VsmStatus vsm_clean_up_zones_root(VsmClient client); +/** + * Retrieve array size + * + * @return array size + */ +unsigned int vsm_addrlist_size(VsmAddrList addrs); + +/** + * Get address type for i'th entry + * + * @return network type (AF_INET or AF_INET6) + */ +int vsm_addrlist_get_type(VsmAddrList addrs, unsigned int i); + +/** + * Get pointer to in_addr property for i'th entry + * see inet_ntop man pages + * + * @return poiner of in_addr + */ +const void *vsm_addrlist_get_addr(VsmAddrList addrs, unsigned int i); + +/** + * Get address prefix for i'th entry + * + * @return adress prefix (mask bits count) + */ +unsigned int vsm_addrlist_get_prefix(VsmAddrList addrs, unsigned int i); + #endif /* __VASUM_WRAPPER_SOURCE__ */ #ifdef __cplusplus