diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-09-10 19:35:49 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-09-10 20:36:12 +0200 |
commit | 93bb49caf4eaf7890b3453bac66b866f1eeae7ed (patch) | |
tree | 7050266be2acee33782a5bb29c1112d7c5817dd6 | |
parent | c7a2b5b32b9dd27e79a5f3079c51cfd7197e9a6a (diff) |
Add implementation of interface_reader::read_interfaces()
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | src/interface_reader.cpp | 61 | ||||
-rw-r--r-- | src/interface_reader.hpp | 5 |
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 |