diff --git a/interface.cpp b/interface.cpp index 56c9ea9..36786a3 100644 --- a/interface.cpp +++ b/interface.cpp @@ -41,82 +41,108 @@ m_index(-1) m_index = Utils::interfaceIndex(interface); } -bool Interface::setLinkUp(QString &error) { +/*! + Set the interface's administrative link state to up. 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::setLinkUp(QString &error) { struct rtnl_link *link, *link_orig = NULL; struct nl_sock *sock = NULL; QByteArray interfaceArray = m_interface.toLatin1(); const char *interface = interfaceArray.constData(); if((sock = Utils::connect())) { - rtnl_link_get_kernel(sock, 0, interface, &link_orig); - - if(rtnl_link_get_kernel(sock, 0, interface, &link) < 0) { + if(rtnl_link_get_kernel(sock, 0, interface, &link_orig) < 0) { std::cerr << "error looking up interface" << std::endl; nl_socket_free(sock); }else{ - unsigned int flags = rtnl_link_get_flags(link); - int err = 0; + if(!link_orig) { + std::cerr << "can't get link" << std::endl; + nl_socket_free(sock); + return 0; + } - flags |= IFF_UP; + link = rtnl_link_alloc(); - rtnl_link_set_flags(link, flags); + if(!link) { + std::cerr << "can't alloc link" << std::endl; + rtnl_link_put(link_orig); + nl_socket_free(sock); + return 0; + } + + int err = 0; + + rtnl_link_set_flags(link, IFF_UP); if((err = rtnl_link_change(sock, link_orig, link, 0)) < 0) { error = nl_geterror(err); rtnl_link_put(link); rtnl_link_put(link_orig); nl_socket_free(sock); - return false; + return 0; } rtnl_link_put(link); rtnl_link_put(link_orig); nl_socket_free(sock); - return true; + return 1; } } - return false; + return 0; } -bool Interface::setLinkDown(QString &error) { +/*! + Set the interface's administrative link state to down. 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::setLinkDown(QString &error) { struct rtnl_link *link, *link_orig = NULL; struct nl_sock *sock = NULL; QByteArray interfaceArray = m_interface.toLatin1(); const char *interface = interfaceArray.constData(); if((sock = Utils::connect())) { - rtnl_link_get_kernel(sock, 0, interface, &link_orig); - - if(rtnl_link_get_kernel(sock, 0, interface, &link) < 0) { + if(rtnl_link_get_kernel(sock, 0, interface, &link_orig) < 0) { std::cerr << "error looking up interface" << std::endl; nl_socket_free(sock); }else{ - unsigned int flags = rtnl_link_get_flags(link); - int err = 0; + if(!link_orig) { + std::cerr << "can't get link" << std::endl; + nl_socket_free(sock); + return 0; + } - flags &= ~IFF_UP; + link = rtnl_link_alloc(); - rtnl_link_set_flags(link, flags); + if(!link) { + std::cerr << "can't alloc link" << std::endl; + rtnl_link_put(link_orig); + nl_socket_free(sock); + return 0; + } + + int err = 0; + + rtnl_link_unset_flags(link, IFF_UP); if((err = rtnl_link_change(sock, link_orig, link, 0)) < 0) { error = nl_geterror(err); rtnl_link_put(link); rtnl_link_put(link_orig); nl_socket_free(sock); - return false; + return 0; } rtnl_link_put(link); rtnl_link_put(link_orig); nl_socket_free(sock); - return true; + return 1; } } - return false; + return 0; } /*!