Commit bdf0784a authored by Dominik Charousset's avatar Dominik Charousset

moved uuid/mac address lookup to own units

parent 0e4a78c0
...@@ -90,6 +90,7 @@ set(LIBCPPA_SRC ...@@ -90,6 +90,7 @@ set(LIBCPPA_SRC
src/actor_addressing.cpp src/actor_addressing.cpp
src/actor_proxy.cpp src/actor_proxy.cpp
src/actor_registry.cpp src/actor_registry.cpp
src/algorithm.cpp
src/any_tuple.cpp src/any_tuple.cpp
src/atom.cpp src/atom.cpp
src/attachable.cpp src/attachable.cpp
...@@ -117,6 +118,8 @@ set(LIBCPPA_SRC ...@@ -117,6 +118,8 @@ set(LIBCPPA_SRC
src/factory.cpp src/factory.cpp
src/fd_util.cpp src/fd_util.cpp
src/fiber.cpp src/fiber.cpp
src/get_root_uuid.cpp
src/get_mac_addresses.cpp
src/group.cpp src/group.cpp
src/group_manager.cpp src/group_manager.cpp
src/ipv4_acceptor.cpp src/ipv4_acceptor.cpp
......
...@@ -307,3 +307,9 @@ unit_testing/test_sync_send.cpp ...@@ -307,3 +307,9 @@ unit_testing/test_sync_send.cpp
unit_testing/test_tuple.cpp unit_testing/test_tuple.cpp
unit_testing/test_uniform_type.cpp unit_testing/test_uniform_type.cpp
unit_testing/test_yield_interface.cpp unit_testing/test_yield_interface.cpp
cppa/util/algorithm.hpp
src/algorithm.cpp
cppa/util/get_mac_addresses.hpp
src/get_mac_addresses.cpp
cppa/util/get_root_uuid.hpp
src/get_root_uuid.cpp
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_UTIL_SPLIT_HPP
#define CPPA_UTIL_SPLIT_HPP
#include <string>
#include <vector>
#include <algorithm>
namespace cppa { namespace util {
std::vector<std::string> split(const std::string& str,
char delim = ' ',
bool keep_empties = true);
template<typename Iterator>
std::string join(Iterator begin, Iterator end) {
std::string result;
std::for_each(begin, end, [&](const std::string& str) {
result += str;
});
return result;
}
} } // namespace cppa::util
#endif // CPPA_UTIL_SPLIT_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_UTIL_GET_MAC_ADDRESSES_HPP
#define CPPA_UTIL_GET_MAC_ADDRESSES_HPP
#include <string>
#include <vector>
namespace cppa { namespace util {
std::vector<std::string> get_mac_addresses();
} } // namespace cppa::util
#endif // CPPA_UTIL_GET_MAC_ADDRESSES_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_UTIL_GET_ROOT_UUID_HPP
#define CPPA_UTIL_GET_ROOT_UUID_HPP
#include <string>
namespace cppa { namespace util {
std::string get_root_uuid();
} } // namespace cppa::util
#endif // CPPA_UTIL_GET_ROOT_UUID_HPP
#include "cppa/util/algorithm.hpp"
#include <sstream>
namespace cppa { namespace util {
std::vector<std::string> split(const std::string& str, char delim, bool keep_empties) {
using namespace std;
vector<string> result;
stringstream strs{str};
string tmp;
while (getline(strs, tmp, delim)) {
if (!tmp.empty() || keep_empties) result.push_back(std::move(tmp));
}
return result;
}
} } // namespace cppa::util
#include "cppa/config.hpp"
#include "cppa/util/get_mac_addresses.hpp"
#ifdef CPPA_MACOS
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory>
#include <sstream>
#include <iostream>
namespace cppa { namespace util {
std::vector<std::string> get_mac_addresses() {
int mib[6];
std::vector<std::string> result;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
auto indices = if_nameindex();
std::unique_ptr<char> buf;
size_t buf_size = 0;
for (auto i = indices; !(i->if_index == 0 && i->if_name == nullptr); ++i) {
mib[5] = i->if_index;
size_t len;
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
perror("sysctl 1 error");
exit(3);
}
if (buf_size < len) {
buf.reset(new char[len]);
buf_size = len;
}
if (sysctl(mib, 6, buf.get(), &len, nullptr, 0) < 0) {
perror("sysctl 2 error");
exit(5);
}
auto ifm = reinterpret_cast<if_msghdr*>(buf.get());
auto sdl = reinterpret_cast<sockaddr_dl*>(ifm + 1);
auto ptr = reinterpret_cast<unsigned char*>(LLADDR(sdl));
auto ctoi = [](char c) -> unsigned {
return static_cast<unsigned char>(c);
};
std::ostringstream oss;
oss << std::hex;
oss.fill('0');
oss.width(2);
oss << ctoi(*ptr++);
for (auto j = 0; j < 5; ++j) {
oss << ":";
oss.width(2);
oss << ctoi(*ptr++);
}
auto addr = oss.str();
if (addr != "00:00:00:00:00:00") result.push_back(std::move(addr));
}
if_freenameindex(indices);
return result;
}
} } // namespace cppa::util
#elif defined(CPPA_LINUX)
#include <vector>
#include <string>
#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
using namespace std;
namespace cppa { namespace util {
std::vector<std::string> get_mac_addresses() {
// get a socket handle
int sck = socket(AF_INET, SOCK_DGRAM, 0);
if (sck < 0) {
perror("socket");
return {};
}
// query available interfaces
char buf[1024] = {0};
ifconf ifc = {0};
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
perror("ioctl(SIOCGIFCONF)");
return {};
}
vector<string> hw_addresses;
auto ctoi = [](char c) -> unsigned {
return static_cast<unsigned char>(c);
};
// iterate through interfaces
auto ifr = ifc.ifc_req;
auto num_ifaces = ifc.ifc_len / sizeof(struct ifreq);
for (int i = 0; i < num_ifaces; i++) {
struct ifreq *item = &ifr[i];
// get mac address
if (ioctl(sck, SIOCGIFHWADDR, item) < 0) {
perror("ioctl(SIOCGIFHWADDR)");
return 1;
}
std::ostringstream oss;
oss << hex;
oss.width(2);
oss << ctoi(item->ifr_hwaddr.sa_data[0]);
for (size_t i = 1; i < 6; ++i) {
oss << ":";
oss.width(2);
oss << ctoi(item->ifr_hwaddr.sa_data[i]);
}
auto addr = oss.str();
if (addr != "00:00:00:00:00:00") {
hw_addresses.push_back(std::move(addr));
}
}
return hw_addresses;
}
} } // namespace cppa::util
#endif
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include "cppa/config.hpp"
#include "cppa/util/get_root_uuid.hpp"
#ifdef CPPA_MACOS
namespace {
inline void erase_trailing_newline(std::string& str) {
while (!str.empty() && (*str.rbegin()) == '\n') {
str.resize(str.size() - 1);
}
}
constexpr const char* s_get_uuid = "/usr/sbin/diskutil info / | "
"/usr/bin/awk '$0 ~ /UUID/ { print $3 }'";
} // namespace <anonymous>
namespace cppa { namespace util {
std::string get_root_uuid() {
char cbuf[100];
// fetch hd serial
std::string uuid;
FILE* get_uuid_cmd = popen(s_get_uuid, "r");
while (fgets(cbuf, 100, get_uuid_cmd) != 0) {
uuid += cbuf;
}
pclose(get_uuid_cmd);
erase_trailing_newline(uuid);
return uuid;
}
} } // namespace cppa::util
#elif defined(CPPA_LINUX)
#include <vector>
#include <string>
#include <cctype>
#include <fstream>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
using namespace std;
struct columns_iterator : iterator<forward_iterator_tag, vector<string>> {
columns_iterator(ifstream* s = nullptr) : fs(s) { }
vector<string>& operator*() { return cols; }
columns_iterator& operator++() {
string line;
if (!getline(*fs, line)) fs = nullptr;
else cols = split(line);
return *this;
}
ifstream* fs;
vector<string> cols;
};
bool operator==(const columns_iterator& lhs, const columns_iterator& rhs) {
return lhs.fs == rhs.fs;
}
bool operator!=(const columns_iterator& lhs, const columns_iterator& rhs) {
return !(lhs == rhs);
}
namespace cppa { namespace util {
std::string get_root_uuid() {
char buf[1024] = {0};
struct ifconf ifc = {0};
struct ifreq *ifr = NULL;
int sck = 0;
int nInterfaces = 0;
// Get a socket handle.
sck = socket(AF_INET, SOCK_DGRAM, 0);
if(sck < 0) {
perror("socket");
return 1;
}
// Query available interfaces.
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
perror("ioctl(SIOCGIFCONF)");
return 1;
}
vector<string> hw_addresses;
auto ctoi = [](char c) -> unsigned {
return static_cast<unsigned char>(c);
};
// Iterate through the list of interfaces.
ifr = ifc.ifc_req;
nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
for(int i = 0; i < nInterfaces; i++) {
struct ifreq *item = &ifr[i];
// Get the MAC address
if(ioctl(sck, SIOCGIFHWADDR, item) < 0) {
perror("ioctl(SIOCGIFHWADDR)");
return 1;
}
std::ostringstream oss;
oss << hex;
oss.width(2);
oss << ctoi(item->ifr_hwaddr.sa_data[0]);
for (size_t i = 1; i < 6; ++i) {
oss << ":";
oss.width(2);
oss << ctoi(item->ifr_hwaddr.sa_data[i]);
}
auto addr = oss.str();
if (addr != "00:00:00:00:00:00") {
hw_addresses.push_back(std::move(addr));
}
}
string uuid;
ifstream fs;
fs.open("/etc/fstab", ios_base::in);
columns_iterator end;
auto i = find_if(columns_iterator{&fs}, end, [](const vector<string>& cols) {
return cols.size() == 6 && cols[1] == "/";
});
if (i != end) {
uuid = move((*i)[0]);
const char cstr[] = { "UUID=" };
auto slen = sizeof(cstr) - 1;
if (uuid.compare(0, slen, cstr) == 0) uuid.erase(0, slen);
// UUIDs are formatted as 8-4-4-4-12 hex digits groups
auto cpy = uuid;
replace_if(cpy.begin(), cpy.end(), ::isxdigit, 'F');
// discard invalid UUID
if (cpy != "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") uuid.clear();
}
for (auto& addr : hw_addresses) {
cout << addr << endl;
}
cout << uuid << endl;
}
} } // namespace cppa::util
#endif // CPPA_LINUX
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/process_information.hpp"
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
...@@ -37,57 +38,20 @@ ...@@ -37,57 +38,20 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include "cppa/util/algorithm.hpp"
#include "cppa/util/ripemd_160.hpp" #include "cppa/util/ripemd_160.hpp"
#include "cppa/process_information.hpp" #include "cppa/util/get_root_uuid.hpp"
#include "cppa/util/get_mac_addresses.hpp"
namespace { namespace {
inline void erase_trailing_newline(std::string& str) {
while (!str.empty() && (*str.rbegin()) == '\n') {
str.resize(str.size() - 1);
}
}
#ifdef CPPA_MACOS
const char* s_get_uuid =
"/usr/sbin/diskutil info / | "
"/usr/bin/awk '$0 ~ /UUID/ { print $3 }'";
const char* s_get_mac =
"/usr/sbin/system_profiler SPNetworkDataType | "
"/usr/bin/grep -Fw MAC | "
"/usr/bin/grep -o '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' | "
"/usr/bin/head -n1";
#elif defined(CPPA_LINUX)
const char* s_get_uuid =
"/bin/egrep -o 'UUID=(([0-9a-fA-F-]+)(-[0-9a-fA-F-]+){3})\\s+/\\s+' "
"/etc/fstab | "
"/bin/egrep -o '([0-9a-fA-F-]+)(-[0-9a-fA-F-]+){3}'";
const char* s_get_mac =
"/sbin/ifconfig | "
"/bin/egrep -o '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' | "
"head -n1";
#endif
cppa::process_information* compute_proc_info() { cppa::process_information* compute_proc_info() {
char cbuf[100]; using namespace cppa::util;
// fetch hd serial auto macs = get_mac_addresses();
std::string hd_serial_and_mac_addr; auto hd_serial_and_mac_addr = join(macs.begin(), macs.end())
FILE* get_uuid_cmd = popen(s_get_uuid, "r"); + get_root_uuid();
while (fgets(cbuf, 100, get_uuid_cmd) != 0) {
hd_serial_and_mac_addr += cbuf;
}
pclose(get_uuid_cmd);
erase_trailing_newline(hd_serial_and_mac_addr);
// fetch mac address of first network device
FILE* get_mac_cmd = popen(s_get_mac, "r");
while (fgets(cbuf, 100, get_mac_cmd) != 0) {
hd_serial_and_mac_addr += cbuf;
}
pclose(get_mac_cmd);
erase_trailing_newline(hd_serial_and_mac_addr);
cppa::process_information::node_id_type node_id; cppa::process_information::node_id_type node_id;
cppa::util::ripemd_160(node_id, hd_serial_and_mac_addr); ripemd_160(node_id, hd_serial_and_mac_addr);
return new cppa::process_information(getpid(), node_id); return new cppa::process_information(getpid(), node_id);
} }
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/binary_serializer.hpp" #include "cppa/binary_serializer.hpp"
#include "cppa/binary_deserializer.hpp" #include "cppa/binary_deserializer.hpp"
#include "cppa/util/get_mac_addresses.hpp"
#include "cppa/util/pt_token.hpp" #include "cppa/util/pt_token.hpp"
#include "cppa/util/is_iterable.hpp" #include "cppa/util/is_iterable.hpp"
...@@ -146,6 +147,12 @@ struct raw_struct_type_info : util::abstract_uniform_type_info<raw_struct> { ...@@ -146,6 +147,12 @@ struct raw_struct_type_info : util::abstract_uniform_type_info<raw_struct> {
int main() { int main() {
CPPA_TEST(test_serialization); CPPA_TEST(test_serialization);
auto addresses = util::get_mac_addresses();
for (auto& addr : addresses) {
cout << addr << endl;
}
return 0;
announce(typeid(raw_struct), new raw_struct_type_info); announce(typeid(raw_struct), new raw_struct_type_info);
network::default_actor_addressing addressing; network::default_actor_addressing addressing;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment