|
@ -1,13 +1,13 @@ |
|
|
// gcc -Wall -Werror -O2 -s -pedantic-errors -std=gnu99 -I/usr/include/libnl3 -o nl-neigh-list nl-neigh-list.c -lnl-route-3 -lnl-3 -lnl-cli-3
|
|
|
// gcc -Wall -Werror -O2 -s -pedantic-errors -std=gnu99 -I/usr/include/libnl3 -o nl-neigh-list nl-neigh-list.c -lnl-route-3 -lnl-3
|
|
|
// armeb-linux-gcc -Wall -Werror -O2 -s -std=gnu99 -I/usr/include/libnl3 -o nl-neigh-list nl-neigh-list.c -L. -lnl-route-3 -lnl-3 -lnl-cli-3 -lnl-nf-3 -lnl-genl-3
|
|
|
// armeb-linux-gcc -Wall -Werror -O2 -s -std=gnu99 -I/usr/include/libnl3 -o nl-neigh-list nl-neigh-list.c -L. -lnl-route-3 -lnl-3 -lnl-nf-3 -lnl-genl-3
|
|
|
// with libs static compiled: armeb-linux-gcc -Wall -Werror -O2 -s -std=gnu99 -I/usr/include/libnl3 -o nl-neigh-list nl-neigh-list.c -L. -Wl,-Bstatic -lnl-route-3 -lnl-3 -lnl-cli-3 -lnl-nf-3 -lnl-genl-3 -Wl,-Bdynamic -lpthread -ldl -lm
|
|
|
// with libs static compiled: armeb-linux-gcc -Wall -Werror -O2 -s -std=gnu99 -I/usr/include/libnl3 -o nl-neigh-list nl-neigh-list.c -L. -Wl,-Bstatic -lnl-route-3 -lnl-3 -lnl-nf-3 -lnl-genl-3 -Wl,-Bdynamic -lpthread -ldl -lm
|
|
|
|
|
|
|
|
|
extern "C" { |
|
|
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 <pthread.h> |
|
|
|
|
|
#include <netlink/socket.h> |
|
|
|
|
|
#include <linux/netlink.h> |
|
|
|
|
|
#include <netlink/netlink.h> |
|
|
|
|
|
#include <netlink/route/addr.h> |
|
|
|
|
|
|
|
|
#include <sys/socket.h> |
|
|
#include <sys/socket.h> |
|
|
#include <netinet/in.h> |
|
|
#include <netinet/in.h> |
|
@ -32,8 +32,8 @@ m_index(-1) |
|
|
m_index = Utils::interfaceIndex(interface); |
|
|
m_index = Utils::interfaceIndex(interface); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Interface::addAddress(QString addressStr) const { |
|
|
int Interface::addAddress(QString addressStr) const { |
|
|
struct nl_sock *sock; |
|
|
struct nl_sock *sock = NULL; |
|
|
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1(); |
|
|
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1(); |
|
|
QByteArray addressArray = addressStr.toLatin1(); |
|
|
QByteArray addressArray = addressStr.toLatin1(); |
|
|
QString bitmask = addressStr.right(2); |
|
|
QString bitmask = addressStr.right(2); |
|
@ -49,30 +49,37 @@ void Interface::addAddress(QString addressStr) const { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
sock = nl_cli_alloc_socket(); |
|
|
if(!(sock = Utils::connect())) { |
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
struct rtnl_addr *addr = rtnl_addr_alloc(); |
|
|
struct rtnl_addr *addr = rtnl_addr_alloc(); |
|
|
|
|
|
|
|
|
|
|
|
if(!addr) { |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
struct nl_addr *address = NULL; |
|
|
struct nl_addr *address = NULL; |
|
|
struct nl_addr *bcast = NULL; |
|
|
struct nl_addr *bcast = NULL; |
|
|
struct nl_msg *result = NULL; |
|
|
struct nl_msg *result = NULL; |
|
|
int parseResult = nl_addr_parse(addressData, AF_UNSPEC, &address); |
|
|
int parseResult = nl_addr_parse(addressData, AF_UNSPEC, &address); |
|
|
int parseBroadcastResult = nl_addr_parse(inet_ntoa(brd), AF_INET, &bcast); |
|
|
|
|
|
|
|
|
|
|
|
if(parseResult != 0) { |
|
|
if(parseResult != 0) { |
|
|
std::cerr << "could not parse address" << std::endl; |
|
|
std::cerr << "could not parse address" << std::endl; |
|
|
rtnl_addr_put(addr); |
|
|
rtnl_addr_put(addr); |
|
|
nl_addr_put(bcast); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
return; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int parseBroadcastResult = nl_addr_parse(inet_ntoa(brd), AF_INET, &bcast); |
|
|
|
|
|
|
|
|
if(parseBroadcastResult != 0) { |
|
|
if(parseBroadcastResult != 0) { |
|
|
std::cerr << "could not parse broadcast address" << std::endl; |
|
|
std::cerr << "could not parse broadcast address" << std::endl; |
|
|
rtnl_addr_put(addr); |
|
|
rtnl_addr_put(addr); |
|
|
nl_addr_put(bcast); |
|
|
nl_addr_put(address); |
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
return; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rtnl_addr_set_ifindex(addr, m_index); |
|
|
rtnl_addr_set_ifindex(addr, m_index); |
|
@ -83,24 +90,34 @@ void Interface::addAddress(QString addressStr) const { |
|
|
|
|
|
|
|
|
if(ret != 0) { |
|
|
if(ret != 0) { |
|
|
std::cerr << "could not build add request" << std::endl; |
|
|
std::cerr << "could not build add request" << std::endl; |
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
|
|
|
nl_addr_put(address); |
|
|
|
|
|
nl_addr_put(bcast); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if(rtnl_addr_add(sock, addr, 0) != 0) { |
|
|
if(rtnl_addr_add(sock, addr, 0) != 0) { |
|
|
std::cerr << "could not add address" << std::endl; |
|
|
std::cerr << "could not add address" << std::endl; |
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
|
|
|
nl_addr_put(address); |
|
|
|
|
|
nl_addr_put(bcast); |
|
|
|
|
|
nlmsg_free(result); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
rtnl_addr_put(addr); |
|
|
|
|
|
nl_addr_put(address); |
|
|
nl_addr_put(bcast); |
|
|
nl_addr_put(bcast); |
|
|
|
|
|
|
|
|
//struct nlmsghdr *hdr = nlmsg_hdr(result);
|
|
|
|
|
|
//nl_msg_dump(result, stderr);
|
|
|
|
|
|
|
|
|
|
|
|
nlmsg_free(result); |
|
|
nlmsg_free(result); |
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Interface::deleteAddress(QString addressStr) const { |
|
|
int Interface::deleteAddress(QString addressStr) const { |
|
|
struct nl_sock *sock; |
|
|
struct nl_sock *sock = NULL; |
|
|
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1(); |
|
|
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1(); |
|
|
QByteArray addressArray = addressStr.toLatin1(); |
|
|
QByteArray addressArray = addressStr.toLatin1(); |
|
|
QString bitmask = addressStr.right(2); |
|
|
QString bitmask = addressStr.right(2); |
|
@ -116,30 +133,38 @@ void Interface::deleteAddress(QString addressStr) const { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
sock = nl_cli_alloc_socket(); |
|
|
if(!(sock = Utils::connect())) { |
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
struct rtnl_addr *addr = rtnl_addr_alloc(); |
|
|
struct rtnl_addr *addr = rtnl_addr_alloc(); |
|
|
struct nl_addr *address = NULL; |
|
|
struct nl_addr *address = NULL; |
|
|
struct nl_addr *bcast = NULL; |
|
|
struct nl_addr *bcast = NULL; |
|
|
struct nl_msg *result = NULL; |
|
|
struct nl_msg *result = NULL; |
|
|
|
|
|
|
|
|
|
|
|
if(!addr) { |
|
|
|
|
|
std::cerr << "could not allocate address" << std::endl; |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int parseResult = nl_addr_parse(addressData, AF_UNSPEC, &address); |
|
|
int parseResult = nl_addr_parse(addressData, AF_UNSPEC, &address); |
|
|
int parseBroadcastResult = nl_addr_parse(inet_ntoa(brd), AF_INET, &bcast); |
|
|
|
|
|
|
|
|
|
|
|
if(parseResult != 0) { |
|
|
if(parseResult != 0) { |
|
|
std::cerr << "could not parse address" << std::endl; |
|
|
std::cerr << "could not parse address" << std::endl; |
|
|
rtnl_addr_put(addr); |
|
|
rtnl_addr_put(addr); |
|
|
nl_addr_put(bcast); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
return; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int parseBroadcastResult = nl_addr_parse(inet_ntoa(brd), AF_INET, &bcast); |
|
|
|
|
|
|
|
|
if(parseBroadcastResult != 0) { |
|
|
if(parseBroadcastResult != 0) { |
|
|
std::cerr << "could not parse broadcast address" << std::endl; |
|
|
std::cerr << "could not parse broadcast address" << std::endl; |
|
|
rtnl_addr_put(addr); |
|
|
rtnl_addr_put(addr); |
|
|
nl_addr_put(bcast); |
|
|
nl_addr_put(address); |
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
return; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rtnl_addr_set_ifindex(addr, m_index); |
|
|
rtnl_addr_set_ifindex(addr, m_index); |
|
@ -150,54 +175,76 @@ void Interface::deleteAddress(QString addressStr) const { |
|
|
|
|
|
|
|
|
if(ret != 0) { |
|
|
if(ret != 0) { |
|
|
std::cerr << "could not build add request" << std::endl; |
|
|
std::cerr << "could not build add request" << std::endl; |
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
|
|
|
nl_addr_put(address); |
|
|
|
|
|
nl_addr_put(bcast); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if(rtnl_addr_delete(sock, addr, 0) != 0) { |
|
|
if(rtnl_addr_delete(sock, addr, 0) != 0) { |
|
|
std::cerr << "could not add address" << std::endl; |
|
|
std::cerr << "could not delete address" << std::endl; |
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
|
|
|
nlmsg_free(result); |
|
|
|
|
|
nl_addr_put(address); |
|
|
|
|
|
nl_addr_put(bcast); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
rtnl_addr_put(addr); |
|
|
|
|
|
nl_addr_put(address); |
|
|
nl_addr_put(bcast); |
|
|
nl_addr_put(bcast); |
|
|
|
|
|
|
|
|
//struct nlmsghdr *hdr = nlmsg_hdr(result);
|
|
|
|
|
|
//nl_msg_dump(result, stderr);
|
|
|
|
|
|
|
|
|
|
|
|
nlmsg_free(result); |
|
|
nlmsg_free(result); |
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Interface::hasCarrier() { |
|
|
bool Interface::hasCarrier(bool *ok) { |
|
|
struct rtnl_link *link; |
|
|
struct rtnl_link *link = NULL; |
|
|
struct nl_sock *sock; |
|
|
struct nl_sock *sock = NULL; |
|
|
QByteArray interfaceArray = m_interface.toLatin1(); |
|
|
QByteArray interfaceArray = m_interface.toLatin1(); |
|
|
const char *interface = interfaceArray.constData(); |
|
|
const char *interface = interfaceArray.constData(); |
|
|
|
|
|
bool carrier = false; |
|
|
|
|
|
|
|
|
sock = nl_cli_alloc_socket(); |
|
|
if((sock = Utils::connect())) { |
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
if(rtnl_link_get_kernel(sock, 0, interface, &link) < 0) { |
|
|
|
|
|
std::cerr << "error looking up interface" << std::endl; |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
}else{ |
|
|
|
|
|
unsigned int flags = rtnl_link_get_flags(link); |
|
|
|
|
|
|
|
|
if(rtnl_link_get_kernel(sock, 0, interface, &link) < 0) { |
|
|
carrier = flags & IFF_RUNNING; |
|
|
std::cerr << "error looking up interface" << std::endl; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsigned int flags = rtnl_link_get_flags(link); |
|
|
rtnl_link_put(link); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
|
|
|
bool carrier = flags & IFF_RUNNING; |
|
|
if(ok != NULL) { |
|
|
|
|
|
*ok = true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
rtnl_link_put(link); |
|
|
return carrier; |
|
|
nl_socket_free(sock); |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(ok != NULL) { |
|
|
|
|
|
*ok = false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return carrier; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
QStringList Interface::addresses() const { |
|
|
QStringList Interface::addresses() const { |
|
|
struct nl_sock *sock; |
|
|
struct nl_sock *sock = NULL; |
|
|
struct rtnl_addr *addr; |
|
|
struct rtnl_addr *addr = NULL; |
|
|
struct nl_cache *addr_cache, *link_cache; |
|
|
struct nl_cache *addr_cache, *link_cache = NULL; |
|
|
struct nl_dump_params params; |
|
|
struct nl_dump_params params; |
|
|
char buf[BUFLEN]; |
|
|
char buf[BUFLEN]; |
|
|
char addrs[ADDRBUFLEN]; |
|
|
char addrs[ADDRBUFLEN]; |
|
|
QByteArray interfaceArray = m_interface.toLatin1(); |
|
|
QByteArray interfaceArray = m_interface.toLatin1(); |
|
|
const char *interface = interfaceArray.constData(); |
|
|
const char *interface = interfaceArray.constData(); |
|
|
|
|
|
char *ipInterface = strndup(interface, strlen(interface)); |
|
|
|
|
|
|
|
|
memset(¶ms, 0, sizeof(struct nl_dump_params)); |
|
|
memset(¶ms, 0, sizeof(struct nl_dump_params)); |
|
|
|
|
|
|
|
@ -206,17 +253,48 @@ QStringList Interface::addresses() const { |
|
|
params.dp_buf = buf; |
|
|
params.dp_buf = buf; |
|
|
params.dp_buflen = BUFLEN; |
|
|
params.dp_buflen = BUFLEN; |
|
|
|
|
|
|
|
|
char *ipInterface = strndup(interface, strlen(interface)); |
|
|
if(!(sock = Utils::connect())) { |
|
|
char *family = const_cast<char*>("inet"); |
|
|
free(ipInterface); |
|
|
|
|
|
return QStringList(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(!(Utils::alloc_addr_cache(sock, &addr_cache))) { |
|
|
|
|
|
free(ipInterface); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return QStringList(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
sock = nl_cli_alloc_socket(); |
|
|
if(!(Utils::alloc_link_cache(sock, &link_cache))) { |
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
free(ipInterface); |
|
|
addr_cache = nl_cli_addr_alloc_cache(sock); |
|
|
nl_cache_free(addr_cache); |
|
|
link_cache = nl_cli_link_alloc_cache(sock); |
|
|
nl_socket_free(sock); |
|
|
addr = nl_cli_addr_alloc(); |
|
|
return QStringList(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
nl_cli_addr_parse_family(addr, family); |
|
|
if(!(addr = rtnl_addr_alloc())) { |
|
|
nl_cli_addr_parse_dev(addr, link_cache, ipInterface); |
|
|
std::cerr << "could not allocate address" << std::endl; |
|
|
|
|
|
free(ipInterface); |
|
|
|
|
|
nl_cache_free(addr_cache); |
|
|
|
|
|
nl_cache_free(link_cache); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return QStringList(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rtnl_addr_set_family(addr, AF_INET); |
|
|
|
|
|
|
|
|
|
|
|
int ival = 0; |
|
|
|
|
|
|
|
|
|
|
|
if(!(ival = rtnl_link_name2i(link_cache, ipInterface))) { |
|
|
|
|
|
std::cerr << "Link " << ipInterface << " does not exist" << std::endl; |
|
|
|
|
|
free(ipInterface); |
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
|
|
|
nl_cache_free(addr_cache); |
|
|
|
|
|
nl_cache_free(link_cache); |
|
|
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
return QStringList(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rtnl_addr_set_ifindex(addr, ival); |
|
|
|
|
|
|
|
|
memset(buf, 0, BUFLEN); |
|
|
memset(buf, 0, BUFLEN); |
|
|
memset(addrs, 0, ADDRBUFLEN); |
|
|
memset(addrs, 0, ADDRBUFLEN); |
|
@ -243,29 +321,30 @@ QStringList Interface::addresses() const { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
nl_object_free(OBJ_CAST(addr)); |
|
|
free(ipInterface); |
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
nl_cache_free(addr_cache); |
|
|
nl_cache_free(addr_cache); |
|
|
nl_cache_free(link_cache); |
|
|
nl_cache_free(link_cache); |
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
free(ipInterface); |
|
|
|
|
|
|
|
|
|
|
|
return addrsList; |
|
|
return addrsList; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
QStringList Interface::list() { |
|
|
QStringList Interface::list() { |
|
|
struct nl_sock *sock; |
|
|
struct nl_sock *sock = NULL; |
|
|
struct nl_cache *link_cache; |
|
|
struct nl_cache *link_cache = NULL; |
|
|
QStringList linkList; |
|
|
QStringList linkList; |
|
|
|
|
|
|
|
|
sock = nl_cli_alloc_socket(); |
|
|
if(!(sock = Utils::connect())) { |
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
return QStringList(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int ret = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache); |
|
|
int ret = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache); |
|
|
|
|
|
|
|
|
if(ret != 0) { |
|
|
if(ret != 0) { |
|
|
std::cerr << "could not allocate link cache" << std::endl; |
|
|
std::cerr << "could not allocate link cache" << std::endl; |
|
|
nl_socket_free(sock); |
|
|
nl_socket_free(sock); |
|
|
return linkList; |
|
|
return QStringList(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int index = 1; |
|
|
int index = 1; |
|
|