Browse Source

add option to set interface state up/down, not working yet (returns "Object busy" from netlink)

master
Brad Parker 11 years ago
parent
commit
8a52a45dd1
  1. 115
      interface.cpp
  2. 3
      interface.h
  3. 51
      tui/menu.cpp

115
interface.cpp

@ -39,6 +39,84 @@ m_index(-1)
m_index = Utils::interfaceIndex(interface);
}
bool 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) {
std::cerr << "error looking up interface" << std::endl;
nl_socket_free(sock);
}else{
unsigned int flags = rtnl_link_get_flags(link);
int err = 0;
flags |= IFF_UP;
rtnl_link_set_flags(link, flags);
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;
}
rtnl_link_put(link);
rtnl_link_put(link_orig);
nl_socket_free(sock);
return true;
}
}
return false;
}
bool 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) {
std::cerr << "error looking up interface" << std::endl;
nl_socket_free(sock);
}else{
unsigned int flags = rtnl_link_get_flags(link);
int err = 0;
flags &= ~IFF_UP;
rtnl_link_set_flags(link, flags);
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;
}
rtnl_link_put(link);
rtnl_link_put(link_orig);
nl_socket_free(sock);
return true;
}
}
return false;
}
/*!
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.
*/
@ -214,6 +292,43 @@ int Interface::deleteAddress(QString addressStr) const {
return 0;
}
/*!
Returns true if the interface is administratively up, otherwise false if it is administratively 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::hasAdminLink(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;
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);
carrier = (flags & IFF_UP) == IFF_UP;
rtnl_link_put(link);
nl_socket_free(sock);
if(ok != NULL) {
*ok = true;
}
return carrier;
}
}
if(ok != NULL) {
*ok = false;
}
return false;
}
/*!
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.
*/

3
interface.h

@ -12,6 +12,9 @@ public:
static QStringList list();
QStringList addresses() const;
bool hasCarrier(bool *ok = 0);
bool hasAdminLink(bool *ok = 0);
bool setLinkUp(QString &error);
bool setLinkDown(QString &error);
int addAddress(QString address) const;
int deleteAddress(QString address) const;
const QString& name() const;

51
tui/menu.cpp

@ -265,6 +265,15 @@ void Menu::interfaceMenu(WINDOW *window) {
interface = QString::number(count) + ". " + interface;
QByteArray interfaceArray = interface.toLatin1();
const char *interfaceStr = interfaceArray.constData();
Interface interfaceObj(orig);
if(interfaceObj.hasCarrier()) {
green(window);
}else if(interfaceObj.hasAdminLink()) {
cyan(window);
}else{
red(window);
}
mvwaddstr(window, y, 2, interfaceStr);
@ -619,9 +628,11 @@ void Menu::interfaceSelect(WINDOW *window, QString interface) {
magenta(window);
mvwaddstr(window, y + 3, 2, "a. Add IP address");
mvwaddstr(window, y + 4, 2, "d. Delete IP address");
mvwaddstr(window, y + 5, 2, "q. Quit");
mvwaddstr(window, y + 5, 2, "+. Set link up");
mvwaddstr(window, y + 6, 2, "-. Set link down");
mvwaddstr(window, y + 7, 2, "q. Quit");
mvwaddstr(window, y + 7, 2, "Enter selection: ");
mvwaddstr(window, y + 9, 2, "Enter selection: ");
wrefresh(window);
char c = getch();
@ -633,7 +644,7 @@ void Menu::interfaceSelect(WINDOW *window, QString interface) {
// no-op, just quit
}else if(c == 'a') {
wdeleteln(window);
mvwaddstr(window, y + 7, 2, "Enter IP address to add: ");
mvwaddstr(window, y + 9, 2, "Enter IP address to add: ");
wrefresh(window);
char ipToAdd[19] = {0};
@ -659,7 +670,7 @@ void Menu::interfaceSelect(WINDOW *window, QString interface) {
QByteArray arr = confirm.toLatin1();
const char *confirmStr = arr.constData();
mvwaddstr(window, y + 7, 2, confirmStr);
mvwaddstr(window, y + 9, 2, confirmStr);
wrefresh(window);
c = getch();
@ -677,7 +688,7 @@ void Menu::interfaceSelect(WINDOW *window, QString interface) {
}
}else if(c == 'd') {
wdeleteln(window);
mvwaddstr(window, y + 7, 2, "Enter number of IP address to delete: ");
mvwaddstr(window, y + 9, 2, "Enter number of IP address to delete: ");
wrefresh(window);
char ipToDelete = getch();
@ -700,7 +711,7 @@ void Menu::interfaceSelect(WINDOW *window, QString interface) {
QByteArray arr = confirm.toLatin1();
const char *confirmStr = arr.constData();
mvwaddstr(window, y + 7, 2, confirmStr);
mvwaddstr(window, y + 9, 2, confirmStr);
wrefresh(window);
c = getch();
@ -716,6 +727,34 @@ void Menu::interfaceSelect(WINDOW *window, QString interface) {
}else{
interfaceSelect(window, interface);
}
}else if(c == '+') {
QString error;
if(!obj.setLinkUp(error)) {
QString err = QString("Could not change link state: ") + error;
QByteArray arr = err.toLatin1();
const char *errorString = arr.constData();
msgbox(errorString);
}else{
msgbox("Link state set to UP.");
}
interfaceSelect(window, interface);
}else if(c == '-') {
QString error;
if(!obj.setLinkDown(error)) {
QString err = QString("Could not change link state: ") + error;
QByteArray arr = err.toLatin1();
const char *errorString = arr.constData();
msgbox(errorString);
}else{
msgbox("Link state set to DOWN.");
}
interfaceSelect(window, interface);
}else{
interfaceSelect(window, interface);
}

Loading…
Cancel
Save