Browse Source

add "addAddress" interface command (for real)

master
Brad Parker 11 years ago
parent
commit
11666a2006
  1. 102
      interface.cpp
  2. 2
      interface.h
  3. 6
      libip.pro
  4. 69
      neighbor.cpp
  5. 1
      neighbor.h

102
interface.cpp

@ -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;
}

2
interface.h

@ -11,9 +11,11 @@ public:
static QStringList list();
QStringList addresses();
bool hasCarrier();
void addAddress(QString address);
private:
QString m_interface;
int m_index;
};
#endif // INTERFACE_H

6
libip.pro

@ -7,10 +7,10 @@ TEMPLATE = lib
TARGET = ip
INCLUDEPATH += /usr/include/libnl3
QMAKE_CXXFLAGS += -Wall -Wextra -Werror
QMAKE_CFLAGS += -Wall -Wextra -Werror
QMAKE_CXXFLAGS += -Wall -Wextra -Werror -fsanitize=address -fPIE
QMAKE_CFLAGS += -Wall -Wextra -Werror -fsanitize=address -fPIE
LIBS += -lnl-route-3 -lnl-3 -lnl-cli-3
LIBS += -lnl-route-3 -lnl-3 -lnl-cli-3 -lasan
HEADERS += interface.h neighbor.h
SOURCES += interface.cpp neighbor.cpp

69
neighbor.cpp

@ -12,6 +12,7 @@ extern "C" {
#define BUFLEN 65535
#define MACBUFLEN 18
#define IPBUFLEN 64
Neighbor::Neighbor(QString interface) :
QObject(0),
@ -23,7 +24,7 @@ m_interface(interface)
QString Neighbor::macOfIP(QString ip) {
struct nl_sock *sock;
struct rtnl_neigh *neigh;
struct nl_cache *neigh_cache;
struct nl_cache *neigh_cache, *link_cache;
struct nl_dump_params params;
char buf[BUFLEN];
char mac[MACBUFLEN];
@ -40,8 +41,15 @@ QString Neighbor::macOfIP(QString ip) {
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);
@ -66,6 +74,7 @@ QString Neighbor::macOfIP(QString ip) {
}
nl_object_free(OBJ_CAST(neigh));
nl_cache_free(link_cache);
nl_cache_free(neigh_cache);
nl_socket_free(sock);
@ -77,3 +86,61 @@ QString Neighbor::macOfIP(QString ip) {
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;
}

1
neighbor.h

@ -9,6 +9,7 @@ Q_OBJECT
public:
Neighbor(QString interface = QString());
QString macOfIP(QString ip);
static QStringList list(QString interface = QString());
private:
QString m_interface;

Loading…
Cancel
Save