Browse Source

remove libnl-cli dependency from Interface class, working on other classes

master
Brad Parker 11 years ago
parent
commit
df53e1c1b7
  1. 211
      interface.cpp
  2. 6
      interface.h
  3. 4
      iptest/iptest.cpp
  4. 30
      neighbor.cpp
  5. 57
      utils.cpp
  6. 4
      utils.h

211
interface.cpp

@ -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
// 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
// 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
// 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-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-nf-3 -lnl-genl-3 -Wl,-Bdynamic -lpthread -ldl -lm
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 <netlink/socket.h>
#include <linux/netlink.h>
#include <netlink/netlink.h>
#include <netlink/route/addr.h>
#include <sys/socket.h>
#include <netinet/in.h>
@ -32,8 +32,8 @@ m_index(-1)
m_index = Utils::interfaceIndex(interface);
}
void Interface::addAddress(QString addressStr) const {
struct nl_sock *sock;
int Interface::addAddress(QString addressStr) const {
struct nl_sock *sock = NULL;
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1();
QByteArray addressArray = addressStr.toLatin1();
QString bitmask = addressStr.right(2);
@ -49,30 +49,37 @@ void Interface::addAddress(QString addressStr) const {
}
}
sock = nl_cli_alloc_socket();
nl_cli_connect(sock, NETLINK_ROUTE);
if(!(sock = Utils::connect())) {
return 1;
}
struct rtnl_addr *addr = rtnl_addr_alloc();
if(!addr) {
nl_socket_free(sock);
return 1;
}
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;
return 1;
}
int parseBroadcastResult = nl_addr_parse(inet_ntoa(brd), AF_INET, &bcast);
if(parseBroadcastResult != 0) {
std::cerr << "could not parse broadcast address" << std::endl;
rtnl_addr_put(addr);
nl_addr_put(bcast);
nl_addr_put(address);
nl_socket_free(sock);
return;
return 1;
}
rtnl_addr_set_ifindex(addr, m_index);
@ -83,24 +90,34 @@ void Interface::addAddress(QString addressStr) const {
if(ret != 0) {
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) {
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);
nl_addr_put(address);
nl_addr_put(bcast);
//struct nlmsghdr *hdr = nlmsg_hdr(result);
//nl_msg_dump(result, stderr);
nlmsg_free(result);
nl_socket_free(sock);
return 0;
}
void Interface::deleteAddress(QString addressStr) const {
struct nl_sock *sock;
int Interface::deleteAddress(QString addressStr) const {
struct nl_sock *sock = NULL;
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1();
QByteArray addressArray = addressStr.toLatin1();
QString bitmask = addressStr.right(2);
@ -116,30 +133,38 @@ void Interface::deleteAddress(QString addressStr) const {
}
}
sock = nl_cli_alloc_socket();
nl_cli_connect(sock, NETLINK_ROUTE);
if(!(sock = Utils::connect())) {
return 1;
}
struct rtnl_addr *addr = rtnl_addr_alloc();
struct nl_addr *address = NULL;
struct nl_addr *bcast = 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 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;
return 1;
}
int parseBroadcastResult = nl_addr_parse(inet_ntoa(brd), AF_INET, &bcast);
if(parseBroadcastResult != 0) {
std::cerr << "could not parse broadcast address" << std::endl;
rtnl_addr_put(addr);
nl_addr_put(bcast);
nl_addr_put(address);
nl_socket_free(sock);
return;
return 1;
}
rtnl_addr_set_ifindex(addr, m_index);
@ -150,54 +175,76 @@ void Interface::deleteAddress(QString addressStr) const {
if(ret != 0) {
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) {
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);
nl_addr_put(address);
nl_addr_put(bcast);
//struct nlmsghdr *hdr = nlmsg_hdr(result);
//nl_msg_dump(result, stderr);
nlmsg_free(result);
nl_socket_free(sock);
return 0;
}
bool Interface::hasCarrier() {
struct rtnl_link *link;
struct nl_sock *sock;
bool Interface::hasCarrier(bool *ok) {
struct rtnl_link *link = NULL;
struct nl_sock *sock = NULL;
QByteArray interfaceArray = m_interface.toLatin1();
const char *interface = interfaceArray.constData();
bool carrier = false;
sock = nl_cli_alloc_socket();
nl_cli_connect(sock, NETLINK_ROUTE);
if((sock = Utils::connect())) {
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) {
std::cerr << "error looking up interface" << std::endl;
}
carrier = flags & IFF_RUNNING;
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);
nl_socket_free(sock);
return carrier;
}
}
if(ok != NULL) {
*ok = false;
}
return carrier;
return false;
}
QStringList Interface::addresses() const {
struct nl_sock *sock;
struct rtnl_addr *addr;
struct nl_cache *addr_cache, *link_cache;
struct nl_sock *sock = NULL;
struct rtnl_addr *addr = NULL;
struct nl_cache *addr_cache, *link_cache = NULL;
struct nl_dump_params params;
char buf[BUFLEN];
char addrs[ADDRBUFLEN];
QByteArray interfaceArray = m_interface.toLatin1();
const char *interface = interfaceArray.constData();
char *ipInterface = strndup(interface, strlen(interface));
memset(&params, 0, sizeof(struct nl_dump_params));
@ -206,17 +253,48 @@ QStringList Interface::addresses() const {
params.dp_buf = buf;
params.dp_buflen = BUFLEN;
char *ipInterface = strndup(interface, strlen(interface));
char *family = const_cast<char*>("inet");
if(!(sock = Utils::connect())) {
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();
nl_cli_connect(sock, NETLINK_ROUTE);
addr_cache = nl_cli_addr_alloc_cache(sock);
link_cache = nl_cli_link_alloc_cache(sock);
addr = nl_cli_addr_alloc();
if(!(Utils::alloc_link_cache(sock, &link_cache))) {
free(ipInterface);
nl_cache_free(addr_cache);
nl_socket_free(sock);
return QStringList();
}
nl_cli_addr_parse_family(addr, family);
nl_cli_addr_parse_dev(addr, link_cache, ipInterface);
if(!(addr = rtnl_addr_alloc())) {
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(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(link_cache);
nl_socket_free(sock);
free(ipInterface);
return addrsList;
}
QStringList Interface::list() {
struct nl_sock *sock;
struct nl_cache *link_cache;
struct nl_sock *sock = NULL;
struct nl_cache *link_cache = NULL;
QStringList linkList;
sock = nl_cli_alloc_socket();
nl_cli_connect(sock, NETLINK_ROUTE);
if(!(sock = Utils::connect())) {
return QStringList();
}
int ret = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache);
if(ret != 0) {
std::cerr << "could not allocate link cache" << std::endl;
nl_socket_free(sock);
return linkList;
return QStringList();
}
int index = 1;

6
interface.h

@ -10,9 +10,9 @@ public:
Interface(QString interface);
static QStringList list();
QStringList addresses() const;
bool hasCarrier();
void addAddress(QString address) const;
void deleteAddress(QString address) const;
bool hasCarrier(bool *ok = 0);
int addAddress(QString address) const;
int deleteAddress(QString address) const;
const QString& name() const;
private:

4
iptest/iptest.cpp

@ -8,10 +8,10 @@
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
Interface interface("enp0s25");
Interface interface("enp0s3");
Neighbor neighbor;
std::cout << "MAC: " << qPrintable(neighbor.macOfIP("10.214.0.1")) << std::endl;
std::cout << "MAC: " << qPrintable(neighbor.macOfIP("10.0.4.1")) << std::endl;
QStringList addresses = interface.addresses();
foreach(QString address, addresses) {

30
neighbor.cpp

@ -7,12 +7,14 @@ extern "C" {
}
#include "neighbor.h"
#include "utils.h"
#include <iostream>
#include <QStringList>
#define BUFLEN 65535
#define MACBUFLEN 18
#define IPBUFLEN 64
#define EMPTY_MAC "00:00:00:00:00:00"
Neighbor::Neighbor(QString interface) :
QObject(0),
@ -22,9 +24,9 @@ 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_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 mac[MACBUFLEN];
@ -38,11 +40,21 @@ QString Neighbor::macOfIP(QString ip) const {
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 QString(EMPTY_MAC);
}
if(!(Utils::alloc_neigh_cache(sock, &neigh_cache))) {
return QString(EMPTY_MAC);
}
if(!(Utils::alloc_link_cache(sock, &link_cache))) {
return QString(EMPTY_MAC);
}
if(!(neigh = rtnl_neigh_alloc())) {
return QString(EMPTY_MAC);
}
if(!m_interface.isEmpty()) {
QByteArray interfaceArray = m_interface.toLatin1();
@ -79,7 +91,7 @@ QString Neighbor::macOfIP(QString ip) const {
nl_socket_free(sock);
if(mac == NULL || count == 0) {
return "00:00:00:00:00:00";
return EMPTY_MAC;
}
QString macStr = mac;

57
utils.cpp

@ -11,6 +11,63 @@ extern "C" {
#include <QTimer>
#include <QtCore/QCoreApplication>
struct nl_sock* Utils::connect() {
struct nl_sock *sock = nl_socket_alloc();
int err = 0;
if(sock == NULL) {
std::cerr << "could not allocate netlink socket" << std::endl;
return 0;
}
if((err = nl_connect(sock, NETLINK_ROUTE)) < 0) {
std::cerr << "could not connect to netlink socket: " << nl_geterror(err) << std::endl;
nl_socket_free(sock);
return 0;
}
return sock;
}
int Utils::alloc_addr_cache(struct nl_sock *sock, struct nl_cache **cache) {
int err = 0;
if((err = rtnl_addr_alloc_cache(sock, cache)) < 0) {
std::cerr << "could not allocate address cache: " << nl_geterror(err) << std::endl;
return 0;
}
nl_cache_mngt_provide(*cache);
return 0;
}
int Utils::alloc_link_cache(struct nl_sock *sock, struct nl_cache **cache) {
int err = 0;
if((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, cache)) < 0) {
std::cerr << "could not allocate link cache: " << nl_geterror(err) << std::endl;
return 0;
}
nl_cache_mngt_provide(*cache);
return 0;
}
int Utils::alloc_neigh_cache(struct nl_sock *sock, struct nl_cache **cache) {
int err = 0;
if((err = rtnl_neigh_alloc_cache(sock, cache)) < 0) {
std::cerr << "could not allocate neighbor cache: " << nl_geterror(err) << std::endl;
return 0;
}
nl_cache_mngt_provide(*cache);
return 0;
}
int Utils::interfaceIndex(QString interface) {
QByteArray array = interface.toLatin1();

4
utils.h

@ -8,6 +8,10 @@ Q_OBJECT
public:
static int interfaceIndex(QString interface);
static struct nl_sock* connect();
static int alloc_addr_cache(struct nl_sock *sock, struct nl_cache **cache);
static int alloc_link_cache(struct nl_sock *sock, struct nl_cache **cache);
static int alloc_neigh_cache(struct nl_sock *sock, struct nl_cache **cache);
};
#endif // LIBIP_UTILS_H

Loading…
Cancel
Save