summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-09-10 19:35:49 +0200
committerMatthias Beyer <mail@beyermatthias.de>2021-09-10 20:36:12 +0200
commit93bb49caf4eaf7890b3453bac66b866f1eeae7ed (patch)
tree7050266be2acee33782a5bb29c1112d7c5817dd6
parentc7a2b5b32b9dd27e79a5f3079c51cfd7197e9a6a (diff)
Add implementation of interface_reader::read_interfaces()
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--src/interface_reader.cpp61
-rw-r--r--src/interface_reader.hpp5
2 files changed, 62 insertions, 4 deletions
diff --git a/src/interface_reader.cpp b/src/interface_reader.cpp
index f685ad0..7c976da 100644
--- a/src/interface_reader.cpp
+++ b/src/interface_reader.cpp
@@ -1,17 +1,72 @@
#include "interface_reader.hpp"
+#include "interface.hpp"
#include "interface_read_error.hpp"
-#include <string>
+
#include <vector>
#include <optional>
-#include <sys/types.h>
+#include <iostream>
+#include <fmt/core.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* To get defns of NI_MAXSERV and NI_MAXHOST */
+#endif // _GNU_SOURCE
+
+#include <arpa/inet.h>
#include <ifaddrs.h>
+#include <linux/if_link.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
-interface_reader::interface_reader(std::vector<std::string> interfaces) : interfaces(interfaces) {
+interface_reader::interface_reader(std::vector<std::string> interfaces) : interface_names(interfaces), interfaces() {
}
std::optional<interface_read_error>
interface_reader::read_interfaces(void)
{
+ struct ifaddrs* interface_addresses;
+ int getifaddrs_result;
+
+ getifaddrs_result = getifaddrs(&interface_addresses);
+
+ if (getifaddrs_result == -1) {
+ // error while reading interfaces
+ return std::optional(interface_read_error("Reading interfaces failed"));
+ }
+
+ char host[NI_MAXHOST];
+
+ for (struct ifaddrs *ifa = interface_addresses; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ std::string interface_name = ifa->ifa_name;
+
+ std::optional<std::string> address;
+ int family = ifa->ifa_addr->sa_family;
+ if (family == AF_INET || family == AF_INET6) {
+ int s = getnameinfo(ifa->ifa_addr,
+ (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6),
+ host, NI_MAXHOST,
+ NULL, 0, NI_NUMERICHOST);
+
+ if (s != 0) {
+ std::string errmsg = fmt::format("getnameinfo() failed for interface '{}': {}", interface_name, gai_strerror(s));
+ return std::optional<interface_read_error>(interface_read_error(errmsg));
+ }
+
+ address = std::optional<std::string>(std::string(host));
+ }
+
+ interface ifc(interface_name, address);
+ this->interfaces.push_back(ifc);
+ }
+
+ freeifaddrs(interface_addresses);
+
return {};
}
diff --git a/src/interface_reader.hpp b/src/interface_reader.hpp
index eed9ad1..149cc43 100644
--- a/src/interface_reader.hpp
+++ b/src/interface_reader.hpp
@@ -3,6 +3,7 @@
#include <string>
#include <vector>
#include <optional>
+#include "interface.hpp"
#include "interface_read_error.hpp"
class interface_reader {
@@ -12,7 +13,9 @@ class interface_reader {
std::optional<interface_read_error> read_interfaces(void);
private:
- std::vector<std::string> interfaces;
+ std::vector<std::string> interface_names;
+
+ std::vector<interface> interfaces;
};
#endif // GETIF_INTERFACE_READER_H