Browse Source

fix error detection in Neighbor member functions, add doxygen documentation/comments for Interface and Neighbor classes

master
Brad Parker 11 years ago
parent
commit
175acacdba
  1. 2331
      Doxyfile
  2. 32
      interface.cpp
  3. 11
      iptest/iptest.cpp
  4. 123
      neighbor.cpp
  5. 5
      neighbor.h
  6. 6
      utils.cpp

2331
Doxyfile

File diff suppressed because it is too large

32
interface.cpp

@ -23,6 +23,14 @@ extern "C" {
#define BUFLEN 65535
#define ADDRBUFLEN BUFLEN
/*!
\class Interface
\brief The Interface class is used to manage IP address information associated with an interface.
*/
/*!
Constructs an Interface object. All operations will be limited to the specified \a interface.
*/
Interface::Interface(QString interface) :
QObject(0),
m_interface(interface),
@ -31,6 +39,9 @@ m_index(-1)
m_index = Utils::interfaceIndex(interface);
}
/*!
Add an IP address to the interface using the CIDR notation, e.g. 192.168.1.1/24. Requires that the CAP_NET_ADMIN capability be set on the application binary, or run as root (\a not \a recommended). Returns 0 on success, 1 on error.
*/
int Interface::addAddress(QString addressStr) const {
struct nl_sock *sock = NULL;
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1();
@ -115,6 +126,9 @@ int Interface::addAddress(QString addressStr) const {
return 0;
}
/*!
Delete an IP address from the interface using the CIDR notation, e.g. 192.168.1.1/24. Requires that the CAP_NET_ADMIN capability be set on the application binary, or run as root (\a not \a recommended). Returns 0 on success, 1 on error.
*/
int Interface::deleteAddress(QString addressStr) const {
struct nl_sock *sock = NULL;
QByteArray addressArrayNoMask = addressStr.left(addressStr.indexOf('/')).toLatin1();
@ -200,6 +214,9 @@ int Interface::deleteAddress(QString addressStr) const {
return 0;
}
/*!
Returns true if the interface is up and running (link-layer is up), and false if the link/interface is down, or if there was an error retrieving the status information. If there was an error, *ok will be set to false, otherwise it will be true.
*/
bool Interface::hasCarrier(bool *ok) {
struct rtnl_link *link = NULL;
struct nl_sock *sock = NULL;
@ -234,6 +251,9 @@ bool Interface::hasCarrier(bool *ok) {
return false;
}
/*!
Returns a list of assigned IP addresses on the interface. All addresses include the subnet mask as CIDR notation (e.g. 192.168.1.1/24).
*/
QStringList Interface::addresses() const {
struct nl_sock *sock = NULL;
struct rtnl_addr *addr = NULL;
@ -257,13 +277,13 @@ QStringList Interface::addresses() const {
return QStringList();
}
if(Utils::alloc_addr_cache(sock, &addr_cache) != 0) {
if(Utils::alloc_addr_cache(sock, &addr_cache)) {
free(ipInterface);
nl_socket_free(sock);
return QStringList();
}
if(Utils::alloc_link_cache(sock, &link_cache) != 0) {
if(Utils::alloc_link_cache(sock, &link_cache)) {
free(ipInterface);
nl_cache_free(addr_cache);
nl_socket_free(sock);
@ -329,6 +349,9 @@ QStringList Interface::addresses() const {
return addrsList;
}
/*!
Returns a list of all interfaces on the system.
*/
QStringList Interface::list() {
struct nl_sock *sock = NULL;
struct nl_cache *link_cache = NULL;
@ -338,7 +361,7 @@ QStringList Interface::list() {
return QStringList();
}
if(Utils::alloc_link_cache(sock, &link_cache) != 0) {
if(Utils::alloc_link_cache(sock, &link_cache)) {
nl_socket_free(sock);
return QStringList();
}
@ -367,6 +390,9 @@ QStringList Interface::list() {
return linkList;
}
/*!
Returns the name of the interface used when the Interface object was constructed.
*/
const QString& Interface::name() const {
return m_interface;
}

11
iptest/iptest.cpp

@ -10,6 +10,7 @@ int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
Interface interface("enp0s3");
Neighbor neighbor;
bool neighOk = false;
std::cout << "MAC: " << qPrintable(neighbor.macOfIP("10.0.4.1")) << std::endl;
QStringList addresses = interface.addresses();
@ -32,17 +33,19 @@ int main(int argc, char *argv[]) {
std::cout << "Neighbors:" << std::endl;
QStringList neighs = Neighbor::list();
QHash<QString, QString> neighs = Neighbor::list("", &neighOk);
foreach(QString neigh, neighs) {
std::cout << qPrintable(neigh) << std::endl;
std::cout << (neighOk ? "(ok)" : "(not ok)") << std::endl;
foreach(QString neigh, neighs.keys()) {
std::cout << qPrintable(neigh) << " (" << qPrintable(neighs.value(neigh)) << ")" << std::endl;
}
std::cout << "-----" << std::endl;
//interface.deleteAddress("1.1.1.5/29");
Wireless wi("wlp3s0");
Wireless wi("wlp0s11u1");
QList<BandInfo> bands = wi.bandMap();

123
neighbor.cpp

@ -17,6 +17,14 @@ extern "C" {
#define IPBUFLEN 64
#define EMPTY_MAC "00:00:00:00:00:00"
/*!
\class Neighbor
\brief The Neighbor class is used to manage ARP table information.
*/
/*!
Constructs a Neighbor object. If \a interface is specified, all operations will be limited to that interface.
*/
Neighbor::Neighbor(QString interface) :
QObject(0),
m_interface(interface)
@ -24,7 +32,10 @@ m_interface(interface)
}
QString Neighbor::macOfIP(QString ip) const {
/*!
Returns the MAC address that has been learned for the IP address \a ip. If the IP address is not in the ARP table or an error retrieving the neighbor occurred, the string "00:00:00:00:00:00" will be returned. If there was an error, *ok will be set to false, otherwise it will be true.
*/
QString Neighbor::macOfIP(QString ip, bool *ok) const {
struct nl_sock *sock = NULL;
struct rtnl_neigh *neigh = NULL;
struct nl_cache *neigh_cache, *link_cache = NULL;
@ -41,17 +52,31 @@ QString Neighbor::macOfIP(QString ip) const {
params.dp_buflen = BUFLEN;
if(!(sock = Utils::connect())) {
if(ok != NULL) {
*ok = false;
}
return QString(EMPTY_MAC);
}
if(!(Utils::alloc_neigh_cache(sock, &neigh_cache))) {
if(Utils::alloc_neigh_cache(sock, &neigh_cache)) {
nl_socket_free(sock);
if(ok != NULL) {
*ok = false;
}
return QString(EMPTY_MAC);
}
if(!(Utils::alloc_link_cache(sock, &link_cache))) {
if(Utils::alloc_link_cache(sock, &link_cache)) {
nl_cache_free(neigh_cache);
nl_socket_free(sock);
if(ok != NULL) {
*ok = false;
}
return QString(EMPTY_MAC);
}
@ -59,6 +84,11 @@ QString Neighbor::macOfIP(QString ip) const {
nl_cache_free(link_cache);
nl_cache_free(neigh_cache);
nl_socket_free(sock);
if(ok != NULL) {
*ok = false;
}
return QString(EMPTY_MAC);
}
@ -74,6 +104,11 @@ QString Neighbor::macOfIP(QString ip) const {
nl_cache_free(neigh_cache);
rtnl_neigh_put(neigh);
nl_socket_free(sock);
if(ok != NULL) {
*ok = false;
}
return QString(EMPTY_MAC);
}
@ -89,6 +124,11 @@ QString Neighbor::macOfIP(QString ip) const {
nl_cache_free(neigh_cache);
rtnl_neigh_put(neigh);
nl_socket_free(sock);
if(ok != NULL) {
*ok = false;
}
return QString(EMPTY_MAC);
}
@ -99,6 +139,11 @@ QString Neighbor::macOfIP(QString ip) const {
nl_cache_free(neigh_cache);
rtnl_neigh_put(neigh);
nl_socket_free(sock);
if(ok != NULL) {
*ok = false;
}
return QString(EMPTY_MAC);
}
@ -133,22 +178,32 @@ QString Neighbor::macOfIP(QString ip) const {
nl_socket_free(sock);
if(mac == NULL || count == 0) {
if(ok != NULL) {
*ok = true;
}
return QString(EMPTY_MAC);
}
QString macStr = mac;
if(ok != NULL) {
*ok = true;
}
return macStr;
}
QStringList Neighbor::list(QString interfaceString) {
/*!
Returns a string hash consisting of IP addresses (both IPv4 and IPv6) in the ARP cache as the keys, and their corresponding MAC addresses as the values. By specifying \a interfaceString the returned list is confined to addresses seen from that named interface. If there are no entries found or if there was an error obtaining the list, an empty hash with no keys are returned. If there was an error, *ok will be set to false, otherwise it will be true.
*/
QHash<QString, QString> Neighbor::list(QString interfaceString, bool *ok) {
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 ip[IPBUFLEN];
QStringList neighborList;
char buf[BUFLEN] = {0};
QHash<QString, QString> neighborList;
memset(&params, 0, sizeof(struct nl_dump_params));
@ -158,18 +213,32 @@ QStringList Neighbor::list(QString interfaceString) {
params.dp_buflen = BUFLEN;
if(!(sock = Utils::connect())) {
return QStringList();
if(ok != NULL) {
*ok = false;
}
return neighborList;
}
if(!(Utils::alloc_link_cache(sock, &link_cache))) {
if(Utils::alloc_link_cache(sock, &link_cache)) {
nl_socket_free(sock);
return QStringList();
if(ok != NULL) {
*ok = false;
}
return neighborList;
}
if(!(Utils::alloc_neigh_cache(sock, &neigh_cache))) {
if(Utils::alloc_neigh_cache(sock, &neigh_cache)) {
nl_cache_free(link_cache);
nl_socket_free(sock);
return QStringList();
if(ok != NULL) {
*ok = false;
}
return neighborList;
}
if(!(neigh = rtnl_neigh_alloc())) {
@ -177,7 +246,12 @@ QStringList Neighbor::list(QString interfaceString) {
nl_cache_free(neigh_cache);
nl_cache_free(link_cache);
nl_socket_free(sock);
return QStringList();
if(ok != NULL) {
*ok = false;
}
return neighborList;
}
if(!interfaceString.isEmpty()) {
@ -191,15 +265,17 @@ QStringList Neighbor::list(QString interfaceString) {
nl_cache_free(neigh_cache);
rtnl_neigh_put(neigh);
nl_socket_free(sock);
return QStringList();
if(ok != NULL) {
*ok = false;
}
return neighborList;
}
rtnl_neigh_set_ifindex(neigh, ival);
}
memset(buf, 0, BUFLEN);
memset(ip, 0, IPBUFLEN);
nl_cache_dump_filter(neigh_cache, &params, OBJ_CAST(neigh));
QString bufString = buf;
@ -212,9 +288,9 @@ QStringList Neighbor::list(QString interfaceString) {
QStringList neighborFields = neighbor.split(' ');
if(neighborFields.count() > 0) {
if(neighborFields[0].contains('.') || neighborFields[0].contains(':')) {
neighborList << neighborFields[0];
if(neighborFields.count() > 3) {
if((neighborFields[0].contains('.') || neighborFields[0].contains(':')) && neighborFields[4].contains(':')) {
neighborList.insert(neighborFields[0], neighborFields[4]);
}
}
}
@ -224,9 +300,16 @@ QStringList Neighbor::list(QString interfaceString) {
nl_cache_free(neigh_cache);
nl_socket_free(sock);
if(ok != NULL) {
*ok = true;
}
return neighborList;
}
/*!
Returns the name of the interface used when creating the Neighbor object. If a name was not provided, an empty string will be returned.
*/
const QString& Neighbor::name() const {
return m_interface;
}

5
neighbor.h

@ -2,6 +2,7 @@
#define LIBIP_NEIGHBOR_H
#include <QObject>
#include <QHash>
#include "libip_global.h"
class LIBIP_EXPORT Neighbor : public QObject {
@ -9,8 +10,8 @@ Q_OBJECT
public:
Neighbor(QString interface = QString());
QString macOfIP(QString ip) const;
static QStringList list(QString interface = QString());
QString macOfIP(QString ip, bool *ok = 0) const;
static QHash<QString, QString> list(QString interface = QString(), bool *ok = 0);
const QString& name() const;
private:

6
utils.cpp

@ -44,9 +44,9 @@ int Utils::alloc_addr_cache(struct nl_sock *sock, struct nl_cache **cache) {
}
int Utils::alloc_link_cache(struct nl_sock *sock, struct nl_cache **cache) {
int err = 0;
int err = rtnl_link_alloc_cache(sock, AF_UNSPEC, cache);
if((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, cache)) < 0) {
if(err != 0) {
std::cerr << "could not allocate link cache: " << nl_geterror(err) << std::endl;
return 1;
}
@ -81,7 +81,7 @@ int Utils::interfaceIndex(QString interface) {
const char *interfaceData = array.constData();
struct nl_cache *link_cache = NULL;
if(Utils::alloc_link_cache(sock, &link_cache) != 0) {
if(Utils::alloc_link_cache(sock, &link_cache)) {
nl_socket_free(sock);
return 0;
}

Loading…
Cancel
Save