From 0c88b9d4b437b187b56b4ff3bc027bd0a79c5b1e Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 15 Aug 2013 22:39:15 -0400 Subject: [PATCH] show mac for an ip and list addresses for an interface --- ip.cpp | 95 +++++++++++++++++++++++++++++++++++++++++------ ip.h | 10 +---- iptest/iptest.cpp | 23 ++++++++++++ iptest/iptest.pro | 18 +++++++++ 4 files changed, 126 insertions(+), 20 deletions(-) create mode 100644 iptest/iptest.cpp create mode 100644 iptest/iptest.pro diff --git a/ip.cpp b/ip.cpp index 08ad2c9..700d457 100644 --- a/ip.cpp +++ b/ip.cpp @@ -5,30 +5,99 @@ extern "C" { #include #include +#include +#include #include } #include "ip.h" +#include +#include + +#define BUFLEN 65535 +#define MACBUFLEN 18 +#define ADDRBUFLEN BUFLEN IP::IP() : -QObject(0), -m_buf(), -m_mac() +QObject(0) { } -const char* IP::get_mac(const char *ip) { +QStringList IP::addresses(const char *interface) { + struct nl_sock *sock; + struct rtnl_addr *addr; + struct nl_cache *addr_cache, *link_cache; + struct nl_dump_params params; + char buf[BUFLEN]; + char addrs[ADDRBUFLEN]; + + memset(¶ms, 0, sizeof(struct nl_dump_params)); + + params.dp_type = NL_DUMP_LINE; + params.dp_fd = NULL; + params.dp_buf = buf; + params.dp_buflen = BUFLEN; + + char *ipInterface = strndup(interface, strlen(interface)); + char *family = const_cast("inet"); + + sock = nl_cli_alloc_socket(); + nl_cli_connect(sock, NETLINK_ROUTE); + addr_cache = nl_cli_addr_alloc_cache(sock); + link_cache = nl_cli_link_alloc_cache(sock); + addr = nl_cli_addr_alloc(); + + nl_cli_addr_parse_family(addr, family); + nl_cli_addr_parse_dev(addr, link_cache, ipInterface); + + memset(buf, 0, BUFLEN); + memset(addrs, 0, ADDRBUFLEN); + + nl_cache_dump_filter(addr_cache, ¶ms, OBJ_CAST(addr)); + + buf[BUFLEN - 1] = '\0'; + + QString addrsString = buf; + QStringList addrsLines = addrsString.split('\n'); + QStringList addrsList; + + foreach(QString addrString, addrsLines) { + QStringList fields = addrString.split(' '); + + if(fields.count() > 0) { + QString address = fields.at(0); + + if(!address.isEmpty()) { + addrsList << fields.at(0); + } + }else{ + std::cerr << "empty line: " << qPrintable(fields.join(' ')) << std::endl; + } + } + + nl_object_free(OBJ_CAST(addr)); + nl_cache_free(addr_cache); + nl_cache_free(link_cache); + nl_socket_free(sock); + free(ipInterface); + + return addrsList; +} + +QString IP::macOfIP(const char *ip) { struct nl_sock *sock; struct rtnl_neigh *neigh; struct nl_cache *neigh_cache; struct nl_dump_params params; + char buf[BUFLEN]; + char mac[MACBUFLEN]; memset(¶ms, 0, sizeof(struct nl_dump_params)); params.dp_type = NL_DUMP_LINE; params.dp_fd = NULL; - params.dp_buf = m_buf; + params.dp_buf = buf; params.dp_buflen = BUFLEN; char *ipAddr = strndup(ip, strlen(ip)); @@ -41,22 +110,22 @@ const char* IP::get_mac(const char *ip) { //case 'f': params.dp_type = nl_cli_parse_dumptype(optarg); break; nl_cli_neigh_parse_dst(neigh, ipAddr); - memset(m_buf, 0, BUFLEN); - memset(m_mac, 0, MACBUFLEN); + memset(buf, 0, BUFLEN); + memset(mac, 0, MACBUFLEN); - nl_cache_dump_filter(neigh_cache, ¶ms, OBJ_CAST(neigh)); + nl_cache_dump_filter(neigh_cache, ¶ms, OBJ_CAST(neigh)); //char data[128] = {0}; unsigned short count = 0; char *rest = NULL; - char *field = strtok_r(m_buf, " ", &rest); + char *field = strtok_r(buf, " ", &rest); while(field != NULL) { ++count; if(count == 5) { if(strstr(field, ":") != NULL) { - memcpy(m_mac, field, MACBUFLEN - 1); + memcpy(mac, field, MACBUFLEN - 1); } } @@ -68,9 +137,11 @@ const char* IP::get_mac(const char *ip) { nl_socket_free(sock); free(ipAddr); - if(m_mac == NULL || count == 0) { + if(mac == NULL || count == 0) { return "00:00:00:00:00:00"; } - return m_mac; + QString macStr = mac; + + return macStr; } diff --git a/ip.h b/ip.h index 0e97035..14419fd 100644 --- a/ip.h +++ b/ip.h @@ -3,19 +3,13 @@ #include -#define BUFLEN 65535 -#define MACBUFLEN 18 - class Q_DECL_EXPORT IP : public QObject { Q_OBJECT public: IP(); - const char* get_mac(const char *ip); - -private: - char m_buf[BUFLEN]; - char m_mac[MACBUFLEN]; + QString macOfIP(const char *ip); + QStringList addresses(const char *interface); }; #endif // IP diff --git a/iptest/iptest.cpp b/iptest/iptest.cpp new file mode 100644 index 0000000..937745d --- /dev/null +++ b/iptest/iptest.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include "ip.h" + +int main(int argc, char *argv[]) { + QCoreApplication app(argc, argv); + IP ip; + + std::cout << "MAC: " << qPrintable(ip.macOfIP("10.0.4.1")) << std::endl; + QStringList addresses = ip.addresses("wlp3s0"); + + foreach(QString address, addresses) { + std::cout << "Address: " << qPrintable(address) << std::endl; + } + + QTimer::singleShot(0, qApp, SLOT(quit())); + + int ret = app.exec(); + + return ret; +} diff --git a/iptest/iptest.pro b/iptest/iptest.pro new file mode 100644 index 0000000..f0a8465 --- /dev/null +++ b/iptest/iptest.pro @@ -0,0 +1,18 @@ +###################################################################### +# Automatically generated by qmake (3.0) Wed Aug 14 06:49:17 2013 +###################################################################### + +QT += core + +TEMPLATE = app +TARGET = iptest + +SOURCES += iptest.cpp + +INCLUDEPATH += "../" + +LIBS += -L.. -lip +LIBS += -lnl-route-3 -lnl-3 -lnl-cli-3 +QMAKE_LFLAGS += -Wl,-rpath,/home/bp/libip + +# Directories