|
|
@ -1,8 +1,9 @@ |
|
|
|
extern "C" { |
|
|
|
#include <netlink/cli/utils.h> |
|
|
|
#include <netlink/cli/neigh.h> |
|
|
|
#include <netlink/cli/addr.h> |
|
|
|
#include <netlink/cli/link.h> |
|
|
|
#include <netlink/socket.h> |
|
|
|
#include <linux/netlink.h> |
|
|
|
#include <netlink/netlink.h> |
|
|
|
#include <netlink/route/link.h> |
|
|
|
#include <netlink/route/neighbour.h> |
|
|
|
#include <pthread.h> |
|
|
|
} |
|
|
|
|
|
|
@ -28,8 +29,7 @@ QString Neighbor::macOfIP(QString ip) const { |
|
|
|
struct rtnl_neigh *neigh = NULL; |
|
|
|
struct nl_cache *neigh_cache, *link_cache = NULL; |
|
|
|
struct nl_dump_params params; |
|
|
|
char buf[BUFLEN]; |
|
|
|
char mac[MACBUFLEN]; |
|
|
|
char buf[BUFLEN] = {0}; |
|
|
|
QByteArray ipArray = ip.toLatin1(); |
|
|
|
char *ipAddr = ipArray.data(); |
|
|
|
|
|
|
@ -45,26 +45,68 @@ QString Neighbor::macOfIP(QString ip) const { |
|
|
|
} |
|
|
|
|
|
|
|
if(!(Utils::alloc_neigh_cache(sock, &neigh_cache))) { |
|
|
|
nl_socket_free(sock); |
|
|
|
return QString(EMPTY_MAC); |
|
|
|
} |
|
|
|
|
|
|
|
if(!(Utils::alloc_link_cache(sock, &link_cache))) { |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QString(EMPTY_MAC); |
|
|
|
} |
|
|
|
|
|
|
|
if(!(neigh = rtnl_neigh_alloc())) { |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QString(EMPTY_MAC); |
|
|
|
} |
|
|
|
|
|
|
|
if(!m_interface.isEmpty()) { |
|
|
|
QByteArray interfaceArray = m_interface.toLatin1(); |
|
|
|
char *interface = interfaceArray.data(); |
|
|
|
nl_cli_neigh_parse_dev(neigh, link_cache, interface); |
|
|
|
|
|
|
|
int ival = 0; |
|
|
|
|
|
|
|
if(!(ival = rtnl_link_name2i(link_cache, interface))) { |
|
|
|
std::cerr << "Link " << interface << " does not exist" << std::endl; |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
rtnl_neigh_put(neigh); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QString(EMPTY_MAC); |
|
|
|
} |
|
|
|
|
|
|
|
rtnl_neigh_set_ifindex(neigh, ival); |
|
|
|
} |
|
|
|
|
|
|
|
nl_cli_neigh_parse_dst(neigh, ipAddr); |
|
|
|
struct nl_addr *addr = NULL; |
|
|
|
int err = 0; |
|
|
|
|
|
|
|
if((err = nl_addr_parse(ipAddr, rtnl_neigh_get_family(neigh), &addr)) < 0) { |
|
|
|
std::cerr << "Unable to parse address \"" << ipAddr << "\": " << nl_geterror(err) << std::endl; |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
rtnl_neigh_put(neigh); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QString(EMPTY_MAC); |
|
|
|
} |
|
|
|
|
|
|
|
if((err = rtnl_neigh_set_dst(neigh, addr)) < 0) { |
|
|
|
std::cerr << "Unable to set local address \"" << ipAddr << "\": " << nl_geterror(err) << std::endl; |
|
|
|
nl_addr_put(addr); |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
rtnl_neigh_put(neigh); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QString(EMPTY_MAC); |
|
|
|
} |
|
|
|
|
|
|
|
nl_addr_put(addr); |
|
|
|
|
|
|
|
memset(buf, 0, BUFLEN); |
|
|
|
|
|
|
|
char mac[MACBUFLEN] = {0}; |
|
|
|
memset(mac, 0, MACBUFLEN); |
|
|
|
|
|
|
|
nl_cache_dump_filter(neigh_cache, ¶ms, OBJ_CAST(neigh)); |
|
|
@ -85,13 +127,13 @@ QString Neighbor::macOfIP(QString ip) const { |
|
|
|
field = strtok_r(NULL, " ", &rest); |
|
|
|
} |
|
|
|
|
|
|
|
nl_object_free(OBJ_CAST(neigh)); |
|
|
|
rtnl_neigh_put(neigh); |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
|
|
if(mac == NULL || count == 0) { |
|
|
|
return EMPTY_MAC; |
|
|
|
return QString(EMPTY_MAC); |
|
|
|
} |
|
|
|
|
|
|
|
QString macStr = mac; |
|
|
@ -100,9 +142,9 @@ QString Neighbor::macOfIP(QString ip) const { |
|
|
|
} |
|
|
|
|
|
|
|
QStringList Neighbor::list(QString interfaceString) { |
|
|
|
struct nl_sock *sock; |
|
|
|
struct rtnl_neigh *neigh; |
|
|
|
struct nl_cache *neigh_cache, *link_cache; |
|
|
|
struct nl_sock *sock = NULL; |
|
|
|
struct rtnl_neigh *neigh = NULL; |
|
|
|
struct nl_cache *neigh_cache, *link_cache = NULL; |
|
|
|
struct nl_dump_params params; |
|
|
|
char buf[BUFLEN]; |
|
|
|
char ip[IPBUFLEN]; |
|
|
@ -115,16 +157,44 @@ QStringList Neighbor::list(QString interfaceString) { |
|
|
|
params.dp_buf = buf; |
|
|
|
params.dp_buflen = BUFLEN; |
|
|
|
|
|
|
|
sock = nl_cli_alloc_socket(); |
|
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
|
neigh_cache = nl_cli_neigh_alloc_cache(sock); |
|
|
|
link_cache = nl_cli_link_alloc_cache(sock); |
|
|
|
neigh = nl_cli_neigh_alloc(); |
|
|
|
if(!(sock = Utils::connect())) { |
|
|
|
return QStringList(); |
|
|
|
} |
|
|
|
|
|
|
|
if(!(Utils::alloc_link_cache(sock, &link_cache))) { |
|
|
|
nl_socket_free(sock); |
|
|
|
return QStringList(); |
|
|
|
} |
|
|
|
|
|
|
|
if(!(Utils::alloc_neigh_cache(sock, &neigh_cache))) { |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QStringList(); |
|
|
|
} |
|
|
|
|
|
|
|
if(!(neigh = rtnl_neigh_alloc())) { |
|
|
|
std::cerr << "could not allocate neighbor" << std::endl; |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QStringList(); |
|
|
|
} |
|
|
|
|
|
|
|
if(!interfaceString.isEmpty()) { |
|
|
|
QByteArray interfaceArray = interfaceString.toLatin1(); |
|
|
|
char *interface = interfaceArray.data(); |
|
|
|
nl_cli_neigh_parse_dev(neigh, link_cache, interface); |
|
|
|
int ival = 0; |
|
|
|
|
|
|
|
if(!(ival = rtnl_link_name2i(link_cache, interface))) { |
|
|
|
std::cerr << "Link " << interface << " does not exist" << std::endl; |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
rtnl_neigh_put(neigh); |
|
|
|
nl_socket_free(sock); |
|
|
|
return QStringList(); |
|
|
|
} |
|
|
|
|
|
|
|
rtnl_neigh_set_ifindex(neigh, ival); |
|
|
|
} |
|
|
|
|
|
|
|
memset(buf, 0, BUFLEN); |
|
|
@ -149,7 +219,7 @@ QStringList Neighbor::list(QString interfaceString) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
nl_object_free(OBJ_CAST(neigh)); |
|
|
|
rtnl_neigh_put(neigh); |
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_cache_free(neigh_cache); |
|
|
|
nl_socket_free(sock); |
|
|
|