|
|
@ -8,20 +8,116 @@ extern "C" { |
|
|
|
#include <netlink/cli/addr.h> |
|
|
|
#include <netlink/cli/link.h> |
|
|
|
#include <pthread.h> |
|
|
|
|
|
|
|
#include <sys/socket.h> |
|
|
|
#include <netinet/in.h> |
|
|
|
#include <arpa/inet.h> |
|
|
|
} |
|
|
|
|
|
|
|
#include "interface.h" |
|
|
|
#include <iostream> |
|
|
|
#include <QStringList> |
|
|
|
#include <QTimer> |
|
|
|
#include <QtGui/QGuiApplication> |
|
|
|
|
|
|
|
#define BUFLEN 65535 |
|
|
|
#define ADDRBUFLEN BUFLEN |
|
|
|
|
|
|
|
Interface::Interface(QString interface) : |
|
|
|
QObject(0), |
|
|
|
m_interface(interface) |
|
|
|
m_interface(interface), |
|
|
|
m_index(-1) |
|
|
|
{ |
|
|
|
QByteArray array = interface.toLatin1(); |
|
|
|
|
|
|
|
struct nl_sock *sock = nl_cli_alloc_socket(); |
|
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
|
|
|
|
|
const char *interfaceData = array.constData(); |
|
|
|
struct nl_cache *link_cache; |
|
|
|
|
|
|
|
int ret = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache); |
|
|
|
|
|
|
|
if(ret != 0) { |
|
|
|
std::cerr << "could not allocate link cache" << std::endl; |
|
|
|
QTimer::singleShot(0, qApp, SLOT(quit())); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
int index = rtnl_link_name2i(link_cache, interfaceData); |
|
|
|
|
|
|
|
m_index = index; |
|
|
|
|
|
|
|
nl_cache_free(link_cache); |
|
|
|
nl_socket_free(sock); |
|
|
|
} |
|
|
|
|
|
|
|
void Interface::addAddress(QString addressStr) { |
|
|
|
struct nl_sock *sock; |
|
|
|
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1(); |
|
|
|
QByteArray addressArray = addressStr.toLatin1(); |
|
|
|
QString bitmask = addressStr.right(2); |
|
|
|
const char *addressDataNoMask = addressArrayNoMask.constData(); |
|
|
|
const char *addressData = addressArray.constData(); |
|
|
|
in_addr_t brdInt = inet_addr(addressDataNoMask); |
|
|
|
struct in_addr brd = { .s_addr = brdInt }; |
|
|
|
int bitlen = bitmask.toInt(); |
|
|
|
|
|
|
|
if(bitlen <= 30) { |
|
|
|
for(int i = 31; i >= bitlen; i--) { |
|
|
|
brd.s_addr |= htonl(1 << (31 - i)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
sock = nl_cli_alloc_socket(); |
|
|
|
nl_cli_connect(sock, NETLINK_ROUTE); |
|
|
|
|
|
|
|
struct rtnl_addr *addr = rtnl_addr_alloc(); |
|
|
|
struct nl_addr *address = NULL; |
|
|
|
struct nl_addr *bcast = NULL; |
|
|
|
struct nl_msg *result = NULL; |
|
|
|
int parseResult = nl_addr_parse(addressData, AF_UNSPEC, &address); |
|
|
|
int parseBroadcastResult = nl_addr_parse(inet_ntoa(brd), AF_INET, &bcast); |
|
|
|
|
|
|
|
if(parseResult != 0) { |
|
|
|
std::cerr << "could not parse address" << std::endl; |
|
|
|
rtnl_addr_put(addr); |
|
|
|
nl_addr_put(bcast); |
|
|
|
nl_socket_free(sock); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if(parseBroadcastResult != 0) { |
|
|
|
std::cerr << "could not parse broadcast address" << std::endl; |
|
|
|
rtnl_addr_put(addr); |
|
|
|
nl_addr_put(bcast); |
|
|
|
nl_socket_free(sock); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
rtnl_addr_set_ifindex(addr, m_index); |
|
|
|
rtnl_addr_set_local(addr, address); |
|
|
|
rtnl_addr_set_broadcast(addr, bcast); |
|
|
|
|
|
|
|
int ret = rtnl_addr_build_add_request(addr, 0, &result); |
|
|
|
|
|
|
|
if(ret != 0) { |
|
|
|
std::cerr << "could not build add request" << std::endl; |
|
|
|
} |
|
|
|
|
|
|
|
if(rtnl_addr_add(sock, addr, 0) != 0) { |
|
|
|
std::cerr << "could not add address" << std::endl; |
|
|
|
} |
|
|
|
|
|
|
|
rtnl_addr_put(addr); |
|
|
|
nl_addr_put(bcast); |
|
|
|
|
|
|
|
//struct nlmsghdr *hdr = nlmsg_hdr(result);
|
|
|
|
//nl_msg_dump(result, stderr);
|
|
|
|
|
|
|
|
nlmsg_free(result); |
|
|
|
nl_socket_free(sock); |
|
|
|
} |
|
|
|
|
|
|
|
bool Interface::hasCarrier() { |
|
|
@ -41,6 +137,7 @@ bool Interface::hasCarrier() { |
|
|
|
|
|
|
|
bool carrier = flags & IFF_RUNNING; |
|
|
|
|
|
|
|
rtnl_link_put(link); |
|
|
|
nl_socket_free(sock); |
|
|
|
|
|
|
|
return carrier; |
|
|
@ -134,7 +231,10 @@ QStringList Interface::list() { |
|
|
|
char *name = rtnl_link_get_name(link); |
|
|
|
|
|
|
|
linkList << name; |
|
|
|
|
|
|
|
rtnl_link_put(link); |
|
|
|
}else{ |
|
|
|
rtnl_link_put(link); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|