From 951db8ebf3f95ec6252f170bef7d3294b7bd6bc8 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 21 Oct 2011 13:11:40 +0200 Subject: now the two versions of the NetworkDiscovery code should be the same (except for the qDebug...) --- CMakeLists.txt | 2 +- NetworkDiscovery/ndgui.cpp | 3 +- NetworkDiscovery/networkdiscovery.cpp | 58 +++++++---- NetworkDiscovery/networkdiscovery.h | 27 +++-- src/ndgui.cpp | 33 +++++-- src/ndgui.h | 2 + src/networkdiscovery.cpp | 103 ++++++++++++++----- src/networkdiscovery.h | 45 +++++---- src/networkmanager.cpp | 179 ++++++++++++++++++++++++++++++++++ src/networkmanager.h | 11 +++ 10 files changed, 381 insertions(+), 82 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78176a4..89139eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} /usr/include/netlink/ /usr/include/netlink/route/ ./customdhcpcd/src/ - ./common/ + ./common ./build ${QT_INCLUDES} /usr/local/Qxt/include/QxtCore diff --git a/NetworkDiscovery/ndgui.cpp b/NetworkDiscovery/ndgui.cpp index 87fda02..c6b1a6d 100644 --- a/NetworkDiscovery/ndgui.cpp +++ b/NetworkDiscovery/ndgui.cpp @@ -29,7 +29,8 @@ ndgui::ndgui(QMainWindow *parent) : _webView->load(QUrl("qrc:html/networkdiscovery_userchoice.html")); _webView->show(); - + + qDebug() << _tag << "start singel shot"; QTimer::singleShot(2000, this, SLOT(prepareNetworkDiscover())); } diff --git a/NetworkDiscovery/networkdiscovery.cpp b/NetworkDiscovery/networkdiscovery.cpp index bac824a..397ea43 100644 --- a/NetworkDiscovery/networkdiscovery.cpp +++ b/NetworkDiscovery/networkdiscovery.cpp @@ -66,23 +66,37 @@ void NetworkDiscovery::initAndRun(QString serverIp, bool userChoice, bool autoUp _dhcpcdArguments.append("-q"); _dhcpcdArguments.append(serverPath); } - if(QFile::exists(serverPath)){ - QFile::remove(serverPath); - } - if(!_server->listen(serverPath)){ - qDebug() << _tag << "Unable to start server: " << _server->errorString(); - abortBoot("Unable to start server: " + _server->errorString()); - return; - } - QFileInfo fInfo(_pathToDhcpcdExe); - if(!fInfo.exists()){ - qDebug() << _tag << "could not find customdhcpcd exe. Please check the path to this file."; - emit emit emit emit abortBoot("could not find customdhcpcd exe. Please check the path to this file."); - return; - } - connect(_server, SIGNAL(newConnection()), this, SLOT(handleNewConnection())); - connect(this, SIGNAL(readyForRun()), this, SLOT(slotReadyForRun())); - if (args != NULL && !args->isEmpty()) { + /* delete the file at serverPath. this is necessary since in case the application crashes, the file still + * exists which leads to an error. + */ + + if(QFile::exists(serverPath)) { + QFile::remove(serverPath); + } + + if (!_server->listen(serverPath)) { + // emit signal to the gui that a critial error occoured + qDebug() << _tag << "Unable to start server: " + << _server->errorString(); + emit + abortBoot("Unable to start server: " + _server->errorString()); + return; + } + + // check if the path to the customdhcpcd file is correct + QFileInfo fInfo(_pathToDhcpcdExe); + if (!fInfo.exists()) { + qDebug() << _tag + << " could not find customdhcpcd exe. Please check the path to this file."; + emit abortBoot( + "could not find customdhcpcd exe. Please check the path to this file."); + return; + } + + connect(_server, SIGNAL(newConnection()), this, SLOT(handleNewConnection())); + connect(this, SIGNAL(readyForRun()), this, SLOT(slotReadyForRun())); + + if (args != NULL && !args->isEmpty()) { qDebug() << _tag << "added additional args"; _dhcpcdArguments.append(*args); } @@ -353,6 +367,9 @@ void NetworkDiscovery::getListOfNetworkInterfacesWithAutoUp() { qDebug() << _tag << " bring up .."; _ifDownList.append(nI.humanReadableName()); } + else if (!(nI.flags() & QNetworkInterface::IsRunning)) { + _ifDownList.append(nI.humanReadableName()); + } } } else { qDebug() << _tag << "no interfaces found!"; @@ -375,11 +392,14 @@ void NetworkDiscovery::getListOfNetworkInterfaces() { || nI.flags() & QNetworkInterface::IsLoopBack) || nI.flags() & QNetworkInterface::IsPointToPoint) || !(nI.flags() & QNetworkInterface::IsUp) - || !(nI.flags() & QNetworkInterface::IsRunning) || checkBlackList(nI.humanReadableName())) { continue; } - _ifUpList.append(nI.humanReadableName()); + if (!(nI.flags() & QNetworkInterface::IsRunning)) { + _ifDownList.append(nI.humanReadableName()); + } else { + _ifUpList.append(nI.humanReadableName()); + } } } else { qDebug() << _tag << "no interfaces found!"; diff --git a/NetworkDiscovery/networkdiscovery.h b/NetworkDiscovery/networkdiscovery.h index 2291a7c..cc79c36 100644 --- a/NetworkDiscovery/networkdiscovery.h +++ b/NetworkDiscovery/networkdiscovery.h @@ -27,16 +27,22 @@ class NetworkDiscovery: public QObject { Q_OBJECT public: - NetworkDiscovery(QObject *parent = 0); - ~NetworkDiscovery(); - void initAndRun(QString serverIp, bool userChoice, bool autoUp, QString pathToLogFile, QString serverPath = DEFAULT_QTSOCKETADDRESS, QString pathToExe = DEFAULT_PATHTODHCPCDEXE, QStringList *args = NULL); - int ip4_replaceDefaultRoute(QString ifName, QString gateway, int mss); - QString getGatewayForInterface(QString ifName); - int ip4_setManualConfiguration(QVariantMap result); - QString readLogFile(); - void tryAgain(); - bool checkConnectivityViaTcp(); - bool checkConnectivityViaTcp(QString server); + NetworkDiscovery(QObject *parent=0); + ~NetworkDiscovery(); + + void initAndRun(QString serverIp, bool userChoice, + bool autoUp, + QString pathToLogFile, + QString serverPath = DEFAULT_QTSOCKETADDRESS, + QString pathToExe = DEFAULT_PATHTODHCPCDEXE, + QStringList* args = NULL); + int ip4_replaceDefaultRoute(QString ifName, QString gateway, int mss); + QString getGatewayForInterface(QString ifName); + + int ip4_setManualConfiguration(QVariantMap result); + QString readLogFile(); + void tryAgain(); + bool checkConnectivityViaTcp(); QVariantMap getInterfaceConfig(QString ifName); private slots: @@ -92,6 +98,7 @@ private: bool checkCarrierState(QString interface); bool checkConnectivity(QString ifName); + bool checkConnectivityViaTcp(QString server); bool checkBlackList(QString i); void getListOfNetworkInterfaces(); diff --git a/src/ndgui.cpp b/src/ndgui.cpp index 8daef9e..c0a390f 100644 --- a/src/ndgui.cpp +++ b/src/ndgui.cpp @@ -7,6 +7,7 @@ ndgui::ndgui(QMainWindow *parent) : _started = false; _userChoice = false; + _tryAgain = false; createAction(); @@ -93,11 +94,15 @@ void ndgui::startNetworkDiscovery(){ disconnect(_webView,SIGNAL(loadFinished(bool)), this, SLOT(startNetworkDiscovery())); if(!_started) { - _started = true; - qxtLog->debug() << _tag << "Initializing networkDiscovery ..."; - QStringList l; - l << "-d"; - networkDiscovery.initAndRun("209.85.148.105", _userChoice, true, "/tmp/fbgui.log","/var/tmp/qt_c_socket_custom", "/bin/cdhcpcd", &l); + if (!_tryAgain) { + _started = true; + QStringList l; + l << "-d"; + networkDiscovery.initAndRun("209.85.148.105", _userChoice, true, "/var/tmp/logfile","/var/tmp/qt_c_socket_custom", DEFAULT_PATHTODHCPCDEXE, &l); + } else { + _tryAgain = false; + networkDiscovery.tryAgain(); + } } else { qxtLog->debug() << _tag << "NetworkDiscovery already started"; @@ -189,9 +194,11 @@ void ndgui::continueBoot(QString ifName, int userChoice) { QString gateway = networkDiscovery.getGatewayForInterface(ifName); networkDiscovery.ip4_replaceDefaultRoute(ifName,gateway,0); } - //_webView->load(QUrl("qrc:html/continueBoot.html")); - emit initFbgui(); - this->hide(); + if (networkDiscovery.checkConnectivityViaTcp()) { + emit initFbgui(); + } else { + abortBoot("Interface was suddenly made unusable "); + } } @@ -208,8 +215,16 @@ QString ndgui::readLogFile() { /**/ void ndgui::tryAgain() { - qxtLog->debug() << _tag << "try again"; + qxtLog->debug()<< _tag << " try again "; + _tryAgain = true; + _started = false; + _ifNameList.clear(); + _manConfList.clear(); + createAction(); + _webView->load(QUrl("qrc:html/networkdiscovery_userchoice.html")); + _webView->show(); + QTimer::singleShot(2000, this, SLOT(prepareNetworkDiscover())); } diff --git a/src/ndgui.h b/src/ndgui.h index ab1f82b..96dac7a 100644 --- a/src/ndgui.h +++ b/src/ndgui.h @@ -58,6 +58,8 @@ private: bool _started; + bool _tryAgain; + QWebView * _webView; QAction * _allowUserChoice; diff --git a/src/networkdiscovery.cpp b/src/networkdiscovery.cpp index 94d1f63..938c504 100644 --- a/src/networkdiscovery.cpp +++ b/src/networkdiscovery.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "networkdiscovery.h" #include "../common/fbgui.h" @@ -97,24 +100,7 @@ void NetworkDiscovery::initAndRun(QString serverIp, bool userChoice, bool autoUp qxtLog->debug() << _tag << "added additional args"; _dhcpcdArguments.append(*args); } - - // start the main work: - if (_autoUp) { - qxtLog->debug() << _tag << " call getListOfNetworkInterfacesWithAutoUp ..."; - getListOfNetworkInterfacesWithAutoUp(); - qxtLog->debug() << _tag << " ifUpList size: " << _ifUpList.size(); - qxtLog->debug() << _tag << " ifDownList size: " << _ifDownList.size(); - - } else { - qxtLog->debug() << _tag << " call getListOfNetworkInterfaces ..."; - getListOfNetworkInterfaces(); - } - - qxtLog->debug() << _tag << " init timer ..."; - _timer = new QTimer(this); - qxtLog->debug() << _tag << " call checkForIsRunning ..."; - connect(_timer, SIGNAL(timeout()), this, SLOT(checkForIsRunning())); - _timer->start(1000); + mainWork(); } @@ -276,9 +262,59 @@ QString NetworkDiscovery::readLogFile() { -/**/ +/* + *TODO: to be bug fixed + *TODO: do it with kill and not QProcess("killall cdhcpcd") + *TODO: still some bugs. if you press tryAgain it can happen that the app stops with the mainscreen. + *TODO: reproducible: start normal with user choice. plug out the cable. press continue. abort screen should appear. + *TODO: press tryAgain. + */ void NetworkDiscovery::tryAgain() { + // kill all cdhcpcd processes + qDebug() << " kill cdhcpcd processes"; + QProcess * p = new QProcess(this); + p->start("killall cdhcpcd"); + p->waitForFinished(); + qDebug() << _tag << "[tryAgain]" << p->errorString(); + /* + foreach(Q_PID pid , _pidsList) { + if (kill(pid,SIGKILL) <= -1) + qDebug() << _tag << " error: trying to kill process: " << pid << " error: " << strerror(errno); + } + */ + // reset everything + _clients.clear(); + _clientProcessToIfNameMap.clear(); + _ifNameToClient.clear(); + _numberOfProcesses = 0; + _blocked = false; + _ifUpCountdown = 10; + _ifUpList.clear(); + _ifDownList.clear(); + _pidsList.clear(); + _ifcMap.clear(); + + // start again + mainWork(); + //SIGK + //kill(); +} + + +/**/ +QVariantMap NetworkDiscovery::getInterfaceConfig(QString ifName) { + QList dns; + interfaceconfiguration * ifc = _ifcMap.value(ifName, NULL); + if (ifc != NULL) { +// +// dns.clear(); +// dns = ifc->getDnsservers().trimmed().split(" "); +// +// //ifc->getIpAddress(), ifc->getNetmask(), ifc->getBroadcast(), +// //ifc->getGateway(), 0, AF_INET, "/etc/", dns); +// + } } @@ -290,6 +326,22 @@ void NetworkDiscovery::tryAgain() { **/ +/**/ +void NetworkDiscovery::mainWork() +{ + if (_autoUp) { + getListOfNetworkInterfacesWithAutoUp(); + _timer = new QTimer(this); + connect(_timer, SIGNAL(timeout()), this, SLOT(checkForIsRunning())); + _timer->start(1000); + + } else { + getListOfNetworkInterfaces(); + emit readyForRun(); + } +} + + /** * searches for usable interfaces and puts them into a list. @@ -364,7 +416,7 @@ void NetworkDiscovery::getListOfNetworkInterfaces() { continue; } if (!(nI.flags() & QNetworkInterface::IsRunning)) { - _ifDownList.append(nI.humanReadableName()) + _ifDownList.append(nI.humanReadableName()); } else { _ifUpList.append(nI.humanReadableName()); } @@ -516,6 +568,13 @@ bool NetworkDiscovery::checkConnectivity(QString ifName) { +/**/ +bool NetworkDiscovery::checkConnectivityViaTcp() { + return checkConnectivityViaTcp(_serverIp); +} + + + /** * try to open a tcp connection to the server * @@ -605,8 +664,8 @@ void NetworkDiscovery::handleNewInput() { QLocalSocket * client = _clients.value(socket); QString data(client->read(DHCP_MESSAGE_SIZE)); - client->write("ACK", ACK_SIZE); - client->waitForBytesWritten(); + //client->write("ACK", ACK_SIZE); + //client->waitForBytesWritten(); data = data.trimmed(); //qxtLog->debug() << _tag << data; QStringList lines = data.split("\n"); diff --git a/src/networkdiscovery.h b/src/networkdiscovery.h index c45b5aa..1f7bd9d 100644 --- a/src/networkdiscovery.h +++ b/src/networkdiscovery.h @@ -21,6 +21,7 @@ #include "dhcp.h" + #define DEFAULT_QTSOCKETADDRESS "/var/tmp/qt_c_socket_default" //#define DEFAULT_PATHTODHCPCDEXE "/home/niklas/fbgui/customdhcpcd/src/build/cdhcpcd" #define DEFAULT_PATHTODHCPCDEXE "/bin/cdhcpcd" @@ -44,6 +45,8 @@ public: int ip4_setManualConfiguration(QVariantMap result); QString readLogFile(); void tryAgain(); + bool checkConnectivityViaTcp(); + QVariantMap getInterfaceConfig(QString ifName); private slots: void handleNewConnection(); @@ -72,26 +75,27 @@ signals: private: QString _tag; - QLocalServer *_server; - QMap _clients; - QLocalSocket * _client; - QMap _ifNameToClient; - QMap _clientProcessToIfNameMap; - QString _pathToDhcpcdExe; - QStringList _dhcpcdArguments; - int _numberOfProcesses; - NetworkManager _networkManager; - bool _userChoice; - bool _blocked; - bool _autoUp; - QString _serverIp; - QString _pathToLogFile; - QList _ifUpList; - QList _ifDownList; - int _ifUpCountdown; - QTimer* _timer; - - QMap _ifcMap; + QLocalServer *_server; + QMap _clients; + QLocalSocket *_client; + QMap _ifNameToClient; + QMap _clientProcessToIfNameMap; + QString _pathToDhcpcdExe; + QStringList _dhcpcdArguments; + int _numberOfProcesses; + NetworkManager _networkManager; + bool _userChoice; + bool _blocked; + bool _autoUp; + QString _serverIp; + QString _pathToLogFile; + QList _ifUpList; + QList _ifDownList; + int _ifUpCountdown; + QTimer *_timer; + QList _pidsList; + QMap _ifcMap; + void mainWork(); void handleNewInput(QLocalSocket * client); @@ -101,6 +105,7 @@ private: bool checkCarrierState(QString interface); bool checkConnectivity(QString ifName); bool checkConnectivityViaTcp(QString server); + bool checkBlackList(QString i); void getListOfNetworkInterfaces(); diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp index da5f045..c40c83d 100644 --- a/src/networkmanager.cpp +++ b/src/networkmanager.cpp @@ -94,6 +94,108 @@ int NetworkManager::replaceDefaultRoute(QString ifname, QString gateway, +/**/ +int NetworkManager::ip6_addRoute(const char *iface, + const struct in6_addr *ip6_dest, int ip6_prefix, + const struct in6_addr *ip6_gateway, int metric, int mss) { + struct nl_cache *cache; + struct nl_handle *nlh; + struct rtnl_route *route; + struct nl_addr *dest_addr; + struct nl_addr *gw_addr = NULL; + int err, iface_idx; + + nlh = nl_handle_alloc(); + nl_connect(nlh, NETLINK_ROUTE); + + if ((cache = rtnl_link_alloc_cache(nlh)) == NULL) { + //qDebug() << _tag << "error with link cache alloc \n"; + printf("error with link cache alloc \n"); + } + + iface_idx = rtnl_link_name2i(cache, iface); + + route = rtnl_route_alloc(); + + /* Destination */ + dest_addr = nl_addr_build(AF_INET6, (struct in6_addr *) ip6_dest, + sizeof(*ip6_dest)); + nl_addr_set_prefixlen(dest_addr, (int) ip6_prefix); + + rtnl_route_set_dst(route, dest_addr); + nl_addr_put(dest_addr); + + /* Gateway */ + if (ip6_gateway && !IN6_IS_ADDR_UNSPECIFIED (ip6_gateway)) { + gw_addr = nl_addr_build(AF_INET6, (struct in6_addr *) ip6_gateway, + sizeof(*ip6_gateway)); + if (gw_addr) { + rtnl_route_set_gateway(route, gw_addr); + rtnl_route_set_scope(route, RT_SCOPE_UNIVERSE); + } else { + rtnl_route_put(route); + return -1; + } + } + + /* Metric */ + if (metric) + rtnl_route_set_prio(route, metric); + + /* Add the route */ + err = rtnl_route_add(nlh, route, 0); + if (err == -ESRCH && ip6_gateway) { + /* Gateway might be over a bridge; try adding a route to gateway first */ + struct rtnl_route *route2; + + route2 = create_route(iface_idx, mss); + if (route2) { + /* Add route to gateway over bridge */ + rtnl_route_set_dst(route2, gw_addr); + err = rtnl_route_add(nlh, route2, 0); + if (!err) { + /* Try adding the route again */ + err = rtnl_route_add(nlh, route, 0); + if (err) + rtnl_route_del(nlh, route2, 0); + } + rtnl_route_put(route2); + } + } + + if (gw_addr) + nl_addr_put(gw_addr); + + if (err) { + //nm_warning ("Failed to set IPv6 route on '%s': %s", iface, nl_geterror ()); + rtnl_route_put(route); + route = NULL; + } + + return 0; +} + + + +struct rtnl_route * NetworkManager::create_route (int iface_idx, int mss) +{ + struct rtnl_route *route; + + route = rtnl_route_alloc (); + if (route) { + rtnl_route_set_oif (route, iface_idx); + + if (mss && rtnl_route_set_metric (route, RTAX_ADVMSS, mss) < 0) { + //nm_warning ("Could not set mss"); + } + } else + //nm_warning ("Could not allocate route"); + + return route; +} + + + /** * The method brings an interface up. * @@ -327,6 +429,83 @@ int NetworkManager::ip4_netmaskToPrefix(QString ipAddr, QString netmask) { +int NetworkManager::ip6_addAddress(struct ip6_addr* ip6Addr, const char *iface) { + int num_addrs, i, iface_idx; + struct rtnl_addr* addr = NULL; + struct nl_cache *cache; + struct nl_handle* rtsock; + + rtsock = nl_handle_alloc(); + nl_connect(rtsock, NETLINK_ROUTE); + + if ((cache = rtnl_link_alloc_cache(rtsock)) == NULL) { + qDebug() << _tag << "error with link cache alloc"; + return -1; + } + + iface_idx = rtnl_link_name2i(cache, iface); + + addr = ip6AddrToRtnlAddr(ip6Addr); + if (!addr) { + //nm_warning("couldn't create rtnl address!\n"); + return -1; + } + rtnl_addr_set_ifindex(addr, iface_idx); + + return sync_address(iface, iface_idx, AF_INET6, addr); +} + + + +/**/ +struct rtnl_addr* NetworkManager::ip6AddrToRtnlAddr(struct ip6_addr* ip6Addr) { + struct rtnl_addr *addr; + bool success = true; + + if (!(addr = rtnl_addr_alloc())) + return NULL; + + success = (nlAddrToRtnlAddr(ip6Addr, addr) >= 0); + + if (!success) { + rtnl_addr_put(addr); + addr = NULL; + } + + return addr; +} + + + +/**/ +struct nl_addr* NetworkManager::ip6AddrToNlAddr(const struct ip6_addr *ip6Addr) { + struct nl_addr * nla = NULL; + + if (!(nla = nl_addr_alloc(sizeof(struct in6_addr)))) + return NULL; + nl_addr_set_family(nla, AF_INET6); + nl_addr_set_binary_addr(nla, (struct in6_addr *) ip6Addr, sizeof(struct in6_addr)); + + return nla; +} + + + +/**/ +int NetworkManager::nlAddrToRtnlAddr( + const struct ip6_addr* ip6Addr, struct rtnl_addr* addr) { + struct nl_addr * local = NULL; + int err = 0; + + local = ip6AddrToNlAddr(ip6Addr); + err = rtnl_addr_set_local(addr, local); + nl_addr_put(local); + + return -err; +} + + + /** * delete all addresses of this interface but not the one we just set * diff --git a/src/networkmanager.h b/src/networkmanager.h index 3fb1587..f332f9e 100644 --- a/src/networkmanager.h +++ b/src/networkmanager.h @@ -38,6 +38,12 @@ public: QString broadcast, QString gateway, int metric, int af, QString pathToResolvConf, QList nameServer); int ip4_configureInterface(QString ifname, QString ipAddress, QString broadcast, QString netmask, int af); + + int ip6_addRoute(const char *iface, + const struct in6_addr *ip6_dest, int ip6_prefix, + const struct in6_addr *ip6_gateway, int metric, int mss); + int ip6_addAddress(struct ip6_addr* ip6Addr, const char *iface); + int writeResolvConf(QString path, QString ifname, QList nameServer); private: @@ -48,6 +54,11 @@ private: int sync_address(const char *iface, int ifindex, int family, struct rtnl_addr *addr); + struct rtnl_route* create_route (int iface_idx, int mss); + struct nl_addr* ip6AddrToNlAddr (const struct ip6_addr* ip6Addr); + int nlAddrToRtnlAddr (const struct ip6_addr* ip6Addr, struct rtnl_addr* addr); + struct rtnl_addr* ip6AddrToRtnlAddr(struct ip6_addr* ip6Addr); + }; -- cgit v1.2.3-55-g7522