summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas2011-09-26 19:41:37 +0200
committerNiklas2011-09-26 19:41:37 +0200
commitc66c1fe54f1fa80ffeea4e28cc2ea2c2117b777c (patch)
tree5d4063c758bdca8931fe13cb96b28a4d79b1631a
parentrenamed routemanager to networkmanager (diff)
downloadfbgui-c66c1fe54f1fa80ffeea4e28cc2ea2c2117b777c.tar.gz
fbgui-c66c1fe54f1fa80ffeea4e28cc2ea2c2117b777c.tar.xz
fbgui-c66c1fe54f1fa80ffeea4e28cc2ea2c2117b777c.zip
added a new function for manual configuration of an interface including a function which writes a resolv.conf
-rw-r--r--LogReceiver/networkdiscovery.cpp3
-rw-r--r--LogReceiver/networkmanager.cpp273
-rw-r--r--LogReceiver/networkmanager.h11
3 files changed, 279 insertions, 8 deletions
diff --git a/LogReceiver/networkdiscovery.cpp b/LogReceiver/networkdiscovery.cpp
index 303ffe7..beca24f 100644
--- a/LogReceiver/networkdiscovery.cpp
+++ b/LogReceiver/networkdiscovery.cpp
@@ -96,6 +96,9 @@ QList<QString> NetworkDiscovery::getListOfNetworkInterfaces() {
|| checkBlackList(nI.humanReadableName())) {
continue;
}
+ if(!(nI.flags() & QNetworkInterface::IsUp)) {
+ networkManager.bringInterfaceUpDown(nI.humanReadableName(), true);
+ }
if (!checkCarrierState(nI.humanReadableName())) {
continue;
}
diff --git a/LogReceiver/networkmanager.cpp b/LogReceiver/networkmanager.cpp
index 9edcf5e..1de0591 100644
--- a/LogReceiver/networkmanager.cpp
+++ b/LogReceiver/networkmanager.cpp
@@ -79,7 +79,7 @@ int NetworkManager::replaceDefaultRoute(QString ifname, QString gateway,
}
retval = rtnl_route_add(rtsock, route, NLM_F_REPLACE);
- qDebug() << "return value:" << retval << ":" << strerror(-retval);
+ qDebug() << "return value:" << retval << ":" << strerror(-retval);
rtnl_route_put(route);
nl_addr_put(gw);
@@ -110,7 +110,7 @@ int NetworkManager::bringInterfaceUpDown(QString ifname, bool up) {
QByteArray ba_ifn = ifname.toAscii();
char * ifn = ba_ifn.data();
- if(!(request = rtnl_link_alloc())) {
+ if (!(request = rtnl_link_alloc())) {
qDebug() << "error. couldn't allocate a rtnl link";
return -1;
}
@@ -118,8 +118,8 @@ int NetworkManager::bringInterfaceUpDown(QString ifname, bool up) {
rtsock = nl_handle_alloc();
nl_connect(rtsock, NETLINK_ROUTE);
- if(up) {
- rtnl_link_set_flags(request,IFF_UP);
+ if (up) {
+ rtnl_link_set_flags(request, IFF_UP);
} else {
rtnl_link_unset_flags(request, IFF_UP);
}
@@ -128,17 +128,16 @@ int NetworkManager::bringInterfaceUpDown(QString ifname, bool up) {
qDebug() << "error with link cache alloc ";
}
- old = rtnl_link_get_by_name(cache,ifn);
+ old = rtnl_link_get_by_name(cache, ifn);
if (old) {
qDebug() << "change link";
retval = rtnl_link_change(rtsock, old, request, 0);
} else {
qDebug() << "change failed";
retval = -1;
- qDebug() << "return value:" << retval << ":" << strerror(-retval);
+ qDebug() << "return value:" << retval << ":" << strerror(-retval);
}
-
rtnl_link_put(old);
rtnl_link_put(request);
nl_handle_destroy(rtsock);
@@ -146,6 +145,261 @@ int NetworkManager::bringInterfaceUpDown(QString ifname, bool up) {
return retval;
}
+int NetworkManager::ip4_setManualConfiguration(QString ifname, QString ipAddress, QString netmask,
+ QString broadcast, QString gateway, int metric, int af, bool up, QString pathToResolvConf, QList<QString> nameServer) {
+ //bring the interface up
+ bringInterfaceUpDown(ifname, up);
+ //set configuration
+ ip4_configureInterface(ifname, ipAddress, broadcast, netmask,af);
+ //set default route
+ replaceDefaultRoute(ifname, gateway, metric, af);
+ //write resolv.conf
+ writeResolvConf(pathToResolvConf, ifname, nameServer);
+
+}
+
+int NetworkManager::ip4_configureInterface(QString ifname, QString ipAddress,
+ QString broadcast, QString netmask, int af) {
+
+ struct nl_cache *cache;
+ struct nl_handle* rtsock;
+ struct nl_addr * local;
+ struct rtnl_addr * addr = NULL;
+ int retval = 0;
+ int iface_idx, err;
+
+ QByteArray ba_ifn = ifname.toAscii();
+ char * ifn = ba_ifn.data();
+
+ QByteArray ba_ip = ipAddress.toAscii();
+ char * ipaddr = ba_ip.data();
+
+ QByteArray ba_bc = broadcast.toAscii();
+ char * bcaddr = ba_bc.data();
+
+ rtsock = nl_handle_alloc();
+ nl_connect(rtsock, NETLINK_ROUTE);
+
+ if ((cache = rtnl_link_alloc_cache(rtsock)) == NULL) {
+ qDebug() << "error with link cache alloc";
+ return -1;
+ }
+
+ iface_idx = rtnl_link_name2i(cache, ifn);
+
+ if (!(addr = rtnl_addr_alloc())) {
+ qDebug() << "error with addr alloc";
+ return -1;
+ }
+
+ local = nl_addr_parse(ipaddr, af);
+ err = rtnl_addr_set_local(addr, local);
+ nl_addr_put(local);
+ if (err != 0) {
+ qDebug() << "error with set local addr";
+ }
+
+ rtnl_addr_set_prefixlen(addr, ip4_netmaskToPrefix(netmask));
+
+ local = nl_addr_parse(bcaddr, af);
+ err = rtnl_addr_set_broadcast(addr, local);
+ nl_addr_put(local);
+ if (err != 0) {
+ qDebug() << "error with set broadcast addr";
+ }
+
+ rtnl_addr_set_ifindex(addr, iface_idx);
+
+ retval = sync_address(ifn, iface_idx, af, addr, 1);
+ if(retval < 0) {
+ qDebug() << "error in sync_address";
+ }
+ rtnl_addr_put(addr);
+
+ return retval;
+}
+
+int NetworkManager::ip4_netmaskToPrefix(QString netmask) {
+ int retval = -1;
+ QNetworkAddressEntry nae;
+
+ if (netmask == "") {
+ qDebug() << "error: netmask is empty";
+ return retval;
+ }
+
+ nae.setNetmask(QHostAddress(netmask));
+ retval = nae.prefixLength();
+
+ return retval;
+}
+
+/**
+ * delete all addresses of this interface but not the one we just set
+ *
+ * @return
+ * -1 if something went wrong. else 0
+ */
+int NetworkManager::sync_address(const char *iface, int ifindex, int family,
+ struct rtnl_addr *addr, int num_addrs) {
+
+ struct nl_handle *nlh;
+ struct nl_cache *addr_cache;
+ struct rtnl_addr *filter_addr, *match_addr;
+ struct nl_object *match;
+ struct nl_addr *nladdr;
+ int err, retval;
+ char buf[INET6_ADDRSTRLEN + 1];
+
+ nlh = nl_handle_alloc();
+ nl_connect(nlh, NETLINK_ROUTE);
+
+ if (!nlh)
+ return -1;
+
+ addr_cache = rtnl_addr_alloc_cache(nlh);
+
+ if (!addr_cache)
+ return -1;
+
+ filter_addr = rtnl_addr_alloc();
+ if (!filter_addr) {
+ nl_cache_free(addr_cache);
+ return -1;
+ }
+ rtnl_addr_set_ifindex(filter_addr, ifindex);
+ if (family)
+ rtnl_addr_set_family(filter_addr, family);
+
+ //nm_log_dbg (log_domain, "(%s): syncing addresses (family %d)", iface, family);
+
+ /* Walk through the cache, comparing the addresses already on
+ * the interface to the addresses in addrs.
+ */
+ for (match = nl_cache_get_first(addr_cache); match; match
+ = nl_cache_get_next(match)) {
+ int buf_valid = -1;
+ match_addr = (struct rtnl_addr *) match;
+
+ /* Skip addresses not on our interface */
+ if (!nl_object_match_filter(match, (struct nl_object *) filter_addr))
+ continue;
+
+ if (addr) {
+ if (addr && nl_object_identical(match, (struct nl_object *) addr)) {
+ continue;
+ }
+ }
+
+ nladdr = rtnl_addr_get_local(match_addr);
+
+ /* Don't delete IPv6 link-local addresses; they don't belong to NM */
+ if (rtnl_addr_get_family(match_addr) == AF_INET6) {
+ struct in6_addr *tmp;
+
+ if (rtnl_addr_get_scope(match_addr) == RT_SCOPE_LINK) {
+ //nm_log_dbg (log_domain, "(%s): ignoring IPv6 link-local address", iface);
+ continue;
+ }
+
+ tmp = (in6_addr*) nl_addr_get_binary_addr(nladdr);
+ if (inet_ntop(AF_INET6, tmp, buf, sizeof(buf)))
+ buf_valid = 0;
+ } else if (rtnl_addr_get_family(match_addr) == AF_INET) {
+ struct in_addr *tmp;
+
+ tmp = (in_addr *) nl_addr_get_binary_addr(nladdr);
+ if (inet_ntop(AF_INET, tmp, buf, sizeof(buf)))
+ buf_valid = 0;
+ }
+
+ if (buf_valid == 0) {
+ //nm_log_dbg (log_domain, "(%s): removing address '%s/%d'",
+ // iface, buf, nl_addr_get_prefixlen (nladdr));
+ }
+
+ /* Otherwise, match_addr should be removed from the interface. */
+ err = rtnl_addr_delete(nlh, match_addr, 0);
+ if (err < 0) {
+ //nm_log_err (log_domain, "(%s): error %d returned from rtnl_addr_delete(): %s",
+ // iface, err, nl_geterror ());
+ qDebug() << "error with delete addr";
+ }
+ }
+
+ rtnl_addr_put(filter_addr);
+ nl_cache_free(addr_cache);
+
+ /* Now add the remaining new addresses */
+ if (!addr)
+ return -1;
+
+ struct in6_addr *in6tmp;
+ struct in_addr *in4tmp;
+ int buf_valid = -1;
+
+ nladdr = rtnl_addr_get_local(addr);
+ if (rtnl_addr_get_family(addr) == AF_INET6) {
+ in6tmp = (in6_addr*) nl_addr_get_binary_addr(nladdr);
+ if (inet_ntop(AF_INET6, in6tmp, buf, sizeof(buf)))
+ buf_valid = 0;
+ } else if (rtnl_addr_get_family(addr) == AF_INET) {
+ in4tmp = (in_addr*) nl_addr_get_binary_addr(nladdr);
+ if (inet_ntop(AF_INET, in4tmp, buf, sizeof(buf)))
+ buf_valid = 0;
+ }
+
+ if (buf_valid == 0) {
+ //nm_log_dbg (log_domain, "(%s): adding address '%s/%d'",
+ //iface, buf, nl_addr_get_prefixlen (nladdr));
+ }
+
+ err = rtnl_addr_add(nlh, addr, 0);
+ if (err < 0) {
+ //nm_log_err (log_domain,
+ // "(%s): error %d returned from rtnl_addr_add():\n%s",
+ // iface, err, nl_geterror ());
+ qDebug() << "error with add addr";
+ }
+
+ rtnl_addr_put(addr);
+
+ return err;
+}
+
+/**
+ * This method writes a resolv.conf file.
+ *
+ * @param path
+ * path to the resolv.conf file. (in most cases: /etc/)
+ * @param ifname
+ * name of the interface
+ * @param
+ * addresses of the nameserver
+ *
+ * @return
+ * return 0 if success
+ * else -1
+ */
+int NetworkManager::writeResolvConf(QString path, QString ifname, QList<QString> nameServer){
+
+ QFile file(path + "resolv.conf");
+ if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ qDebug() << "error couldn't open file:" << path;
+ return -1;
+ }
+ QTextStream out(&file);
+ out << "# Generated by networkdiscovery manual configuration for interface " + ifname +"\n";
+ foreach(QString ns, nameServer ) {
+ out << "nameserver " + ns +"\n";
+ }
+
+ file.close();
+
+ return 0;
+}
+
+
/**
* This method adds or deletes a route.
* This method adds or deletes a route. According to the action,
@@ -175,4 +429,7 @@ int NetworkManager::bringInterfaceUpDown(QString ifname, bool up) {
* return 1 if an error happened.
* return 0 if everything was ok.
*/
-int NetworkManager::doRoute(QString ifName, QString destination, QString gateway, int af, int action) {return 0;}
+int NetworkManager::doRoute(QString ifName, QString destination,
+ QString gateway, int af, int action) {
+ return 0;
+}
diff --git a/LogReceiver/networkmanager.h b/LogReceiver/networkmanager.h
index edcce28..9834d28 100644
--- a/LogReceiver/networkmanager.h
+++ b/LogReceiver/networkmanager.h
@@ -12,12 +12,14 @@
#include <interface.h>
#include <netlink/netlink.h>
#include <netlink/netlink-kernel.h>
+#include <netlink/route/addr.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/route.h>
#include <netlink/route/link.h>
#include <errno.h>
#include <QtCore>
+#include <QNetworkAddressEntry>
class NetworkManager: public QObject {
Q_OBJECT
@@ -33,7 +35,16 @@ public:
int af);
int bringInterfaceUpDown(QString ifname, bool up);
+ int ip4_setManualConfiguration(QString ifname, QString ipAddress, QString netmask,
+ QString broadcast, QString gateway, int metric, int af, bool up, QString pathToResolvConf, QList<QString> nameServer);
+
private:
+ int ip4_netmaskToPrefix(QString netmask);
+ int ip4_configureInterface(QString ifname, QString ipAddress,
+ QString broadcast, QString netmask, int af);
+ int sync_address(const char *iface, int ifindex, int family,
+ struct rtnl_addr *addr, int num_addrs);
+ int writeResolvConf(QString path, QString ifname, QList<QString> nameServer);
};