You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.4 KiB

extern "C" {
#include <netlink/cli/utils.h>
#include <netlink/cli/neigh.h>
#include <netlink/cli/addr.h>
#include <netlink/cli/link.h>
#include <pthread.h>
}
#include "neighbor.h"
#include <iostream>
#include <QStringList>
#define BUFLEN 65535
#define MACBUFLEN 18
#define IPBUFLEN 64
Neighbor::Neighbor(QString interface) :
QObject(0),
m_interface(interface)
{
}
QString Neighbor::macOfIP(QString ip) const {
struct nl_sock *sock;
struct rtnl_neigh *neigh;
struct nl_cache *neigh_cache, *link_cache;
struct nl_dump_params params;
char buf[BUFLEN];
char mac[MACBUFLEN];
QByteArray ipArray = ip.toLatin1();
char *ipAddr = ipArray.data();
memset(&params, 0, sizeof(struct nl_dump_params));
params.dp_type = NL_DUMP_LINE;
params.dp_fd = NULL;
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(!m_interface.isEmpty()) {
QByteArray interfaceArray = m_interface.toLatin1();
char *interface = interfaceArray.data();
nl_cli_neigh_parse_dev(neigh, link_cache, interface);
}
nl_cli_neigh_parse_dst(neigh, ipAddr);
memset(buf, 0, BUFLEN);
memset(mac, 0, MACBUFLEN);
nl_cache_dump_filter(neigh_cache, &params, OBJ_CAST(neigh));
unsigned short count = 0;
char *rest = NULL;
char *field = strtok_r(buf, " ", &rest);
while(field != NULL) {
++count;
if(count == 5) {
if(strstr(field, ":") != NULL) {
memcpy(mac, field, MACBUFLEN - 1);
}
}
field = strtok_r(NULL, " ", &rest);
}
nl_object_free(OBJ_CAST(neigh));
nl_cache_free(link_cache);
nl_cache_free(neigh_cache);
nl_socket_free(sock);
if(mac == NULL || count == 0) {
return "00:00:00:00:00:00";
}
QString macStr = mac;
return macStr;
}
QStringList Neighbor::list(QString interfaceString) {
struct nl_sock *sock;
struct rtnl_neigh *neigh;
struct nl_cache *neigh_cache, *link_cache;
struct nl_dump_params params;
char buf[BUFLEN];
char ip[IPBUFLEN];
QStringList neighborList;
memset(&params, 0, sizeof(struct nl_dump_params));
params.dp_type = NL_DUMP_LINE;
params.dp_fd = NULL;
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(!interfaceString.isEmpty()) {
QByteArray interfaceArray = interfaceString.toLatin1();
char *interface = interfaceArray.data();
nl_cli_neigh_parse_dev(neigh, link_cache, interface);
}
memset(buf, 0, BUFLEN);
memset(ip, 0, IPBUFLEN);
nl_cache_dump_filter(neigh_cache, &params, OBJ_CAST(neigh));
QString bufString = buf;
QStringList list = bufString.split('\n');
foreach(QString neighbor, list) {
if(neighbor.isEmpty()) {
continue;
}
QStringList neighborFields = neighbor.split(' ');
if(neighborFields.count() > 0) {
if(neighborFields[0].contains('.') || neighborFields[0].contains(':')) {
neighborList << neighborFields[0];
}
}
}
nl_object_free(OBJ_CAST(neigh));
nl_cache_free(link_cache);
nl_cache_free(neigh_cache);
nl_socket_free(sock);
return neighborList;
}
const QString& Neighbor::name() const {
return m_interface;
}