OK335xS Qt network hacking

/**********************************************************************
 *                  OK335xS Qt network hacking
 * 说明:
 *     应该半年前尝试过来解读这个程序,但是那时候对有些东西不是很理解,
 * 最后不了了之了,这次因为需要,所以重新对network的mainwindow.cpp进行
 * 一下解读。
 *
 *                                    2016-4-8 深圳 南山平山村 曾剑锋
 *********************************************************************/


#include "mainwindow.h"
#include "ui_mainwindow.h"

// ifconfig -a|grep -E "eth[0-9]|wlan[0-9]"|cut -d' ' -f 1
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    // 设置UI界面
    ui->setupUi(this);
    proc = NULL;
    flag = false;
    // 选择的网卡发生了改变
    connect(ui->cb_interface, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(on_sel_changed(QString)));
    // 点击了OK按j钮
    connect(ui->ok, SIGNAL(clicked()), this, SLOT(on_ok_clicked()));
    // 选择了dhcp单选按钮
    connect(ui->radio_dhcp, SIGNAL(toggled(bool)), this, SLOT(on_toggled(bool)));
    // 选择了static单选按钮
    connect(ui->radio_static, SIGNAL(toggled(bool)), this, SLOT(on_toggled(bool)));

    // 获取当前系统中的网卡,并创建对应的网卡实例
    refreshInterfaces();
    // 读取当前系统默认对网卡的配置
    readConfigs();

    // 将当前默认的网卡的数据显示
    on_sel_changed(ui->cb_interface->currentText());

}

MainWindow::~MainWindow()
{
    delete ui;
    // 释放实例化的网卡实例
    foreach(Interface *i,ints)
        delete i;
}

void MainWindow::state(bool dhcp)
{
    // 设置UI显示状态
    if(dhcp)
    {
        ui->radio_dhcp->setChecked(true);
        ui->radio_static->setChecked(false);
        ui->edt_ip->setDisabled(true);
        ui->edt_mask->setDisabled(true);
        ui->edt_gateway->setDisabled(true);
        ui->edt_dns->setDisabled(true);
    }
    else
    {
        ui->radio_dhcp->setChecked(false);
        ui->radio_static->setChecked(true);
        ui->edt_ip->setDisabled(false);
        ui->edt_mask->setDisabled(false);
        ui->edt_gateway->setDisabled(false);
        ui->edt_dns->setDisabled(false);
    }
}

void MainWindow::refreshInterfaces()
{
    QStringList sl;

    /*过滤读eth[0-9] wlan[0-9]*/
    // 获取网卡名保存在/tmp/interfaces文件中,一行一个网卡名
    ::system("ifconfig -a|grep -E \"eth[0-9]\"|cut -d' ' -f 1 >/tmp/interfaces");
    // 打开缓存文件
    QFile f("/tmp/interfaces");
    if(f.open(QFile::ReadOnly))
    {
        // 创建文件流
        QTextStream t(&f);
        // 判断是否到了文件末尾
        while(!t.atEnd())
        {
            // 获取一行,也就是一个网卡名
            QString str=t.readLine();
            if(str.size()>0)
            {
                //QMessageBox::about(this,"aaa",str);
                /**
                 * 1. QList<Interface*> ints;
                 * 2. class Interface
                 *       {
                 *       public:
                 *           Interface(QString &name);
                 *       public:
                 *           QString name;
                 *           bool    dhcp;
                 *           QString ip;
                 *           QString mask;
                 *           QString gateway;
                 *           QString dns;
                 *       };
                 * 3. 实例化网卡,添加在list后面
                 * 4. 与后面的c_interface的index是一样的
                 *
                 */
                ints.append(new Interface(str));
                sl<<str;
            }
        }
    }
    f.close();

    ui->cb_interface->addItems(sl);
}

void MainWindow::readConfigs()
{
    /*自己的配置文件*/
    foreach(Interface *i,ints)
    {
        // 获取几个网卡的默认配置信息
        QFile f("/etc/network/.conf/"+i->name);
        if(f.open(QFile::ReadOnly))
        {
            QTextStream t(&f);
            QString str = t.readLine();

            if(str == "dhcp")//do nothing
                ;
            // 从下面的内容可以知道,配置信息的循序必须按照下面读取的顺序进行排序写,
            // 否则会照成配置出错
            else if(str == "static")
            {
                i->dhcp = false;
                i->ip = t.readLine();
                i->mask = t.readLine();
                i->gateway = t.readLine();
                i->dns = t.readLine();
            }
        }
        f.close();
    }
}

/**
 * @brief ip2int
 * @param ip
 * @return
 *
 * 将IP地址转化成整数
 */
unsigned int ip2int(QString ip)
{
    QStringList sl = ip.split('.');
    unsigned int r = 0;
    foreach(QString s,sl)
    {
        r <<= 8;
        r |= s.toUInt();
    }

    return r;
}

/**
 * @brief int2ip
 * @param ip
 * @return
 *
 * 将int型整数,转化成点分十进制IP
 */
QString int2ip(unsigned int ip)
{
    return QString::number((ip >> 24) & 0xff) + "." + QString::number((ip >> 16) & 0xff)
            + "." + QString::number((ip >> 8) & 0xff) + "." + QString::number(ip & 0xff);
}

void MainWindow::writeConfigs()
{
    /*真正的配置文件*/
    // 域名服务器IP
    ::system("rm /etc/resolv.conf");
    QFile r("/etc/resolv.conf");//for dns
    QTextStream *t2 = NULL;
    if(r.open(QFile::WriteOnly))
    {
        t2 = new QTextStream(&r);
    }

    // 网卡参数
    QFile m("/etc/network/interfaces");//for interface
    QTextStream *t3 = NULL;
    if(m.open(QFile::WriteOnly))
    {
        t3 = new QTextStream(&m);
    }

    /*write `lo` configration first*/
    *t3<<QString("auto lo\n");
    *t3<<QString("iface lo inet loopback\n");

    ::system("mkdir -p /etc/network/.conf");

    /*自己的配置文件*/
    // 重写配置文件
    foreach(Interface *i,ints)
    {
        QFile f("/etc/network/.conf/"+i->name);

        if(f.open(QFile::WriteOnly))
        {
            QTextStream t(&f);

            if(i->dhcp)
            {
                t<<QString("dhcp")<<QString(QString("\n"));
                *t3<<QString("auto ")<<i->name<<QString(QString("\n"));
                *t3<<QString("iface ")<<i->name<<QString(" inet dhcp\n");
            }
            else
            {
                t<<QString("static")<<QString("\n");
                t<<i->ip<<QString("\n");
                t<<i->mask<<QString("\n");
                t<<i->gateway<<QString("\n");
                t<<i->dns<<QString("\n");

                *t3<<QString("auto ")<<i->name<<QString("\n");
                *t3<<QString("iface ")<<i->name<<QString(" inet static\n");
                *t3<<QString("address ")<<i->ip<<QString("\n");
                *t3<<QString("netmask ")<<i->mask<<QString("\n");
                *t3<<QString("gateway ")<<i->gateway<<QString("\n");
                *t3<<QString("broadcast ")<<int2ip((ip2int(i->ip) & ip2int(i->mask))|(~ip2int(i->mask)))<<QString("\n");

                *t2<<QString("nameserver ")+i->dns<<QString("\n");//同时写入到/etc/resolv.conf
            }
        }
        f.close();
    }

    delete t2;
    delete t3;

    r.close();
    m.close();
}

void MainWindow::on_toggled(bool b)
{
    // 通过这里知道当前索引的那张网卡
    Interface *i = NULL;
    foreach(i,ints)
    {
        if(i->name == ui->cb_interface->currentText())
            break;
    }

    // 根据当前的是否采用dhcp还是static来显示UI控件
    state(ui->radio_dhcp->isChecked());

    // 显示对应的数据
    if(ui->radio_dhcp->isChecked())
    {
        /*ui->edt_ip->clear();
        ui->edt_mask->clear();
        ui->edt_gateway->clear();
        ui->edt_dns->clear();*/
    }
    else
    {
        ui->edt_ip->setText(i->ip);
        ui->edt_mask->setText(i->mask);
        ui->edt_gateway->setText(i->gateway);
        ui->edt_dns->setText(i->dns);
    }
}

void MainWindow::on_sel_changed(const QString &text)
{
    // 循环检查,如果当前次循环的网卡实例名与传入的参数一样,那么跳出循环,
    // i则指向了当前需要配置的网卡
    Interface *i = NULL;
    foreach(i,ints)
    {
        if(i->name == text)
            break;
    }

    //QMessageBox::about(this,"aaa",i->name);

    // 设置UI显示状态
    state(i->dhcp);

    // 重新设置UI中的值
    if(i->dhcp)
    {
        ui->edt_ip->clear();
        ui->edt_mask->clear();
        ui->edt_gateway->clear();
        ui->edt_dns->clear();
    }
    else
    {
        ui->edt_ip->setText(i->ip);
        ui->edt_mask->setText(i->mask);
        ui->edt_gateway->setText(i->gateway);
        ui->edt_dns->setText(i->dns);
    }
}

void MainWindow::on_ok_clicked()
{
    // 获取当前的网jjj卡
    Interface *i = NULL;
    foreach(i,ints)
    {
        if(i->name == ui->cb_interface->currentText())
            break;
    }

    // 设置当前的网卡
    i->dhcp     = ui->radio_dhcp->isChecked();
    i->ip         = ui->edt_ip->text();
    i->mask     = ui->edt_mask->text();
    i->gateway     = ui->edt_gateway->text();
    i->dns         = ui->edt_dns->text();

    // 写入文件
    writeConfigs();
    // 同步,将内存中的数据写入NAND或者SD卡
    ::system("sync");

    // 如果proc存在,那么就释放
    if(proc)
        delete proc;

    // 创建进程来重启网卡
    proc = new QProcess(this);
    proc->start("/etc/init.d/networking restart");
    // 防止进程未处理完之前,程序退出
    connect(proc,SIGNAL(finished(int)),this,SLOT(proc_finished(int)));
    this->setDisabled(true);

    flag = true;
}

void MainWindow::closeEvent(QCloseEvent * evt)
{
    if(flag)
    {
        evt->ignore();
        QMessageBox::about(this,"info","network is restarting,please wait");
    }
    else
    {
        destroy();
        exit(0);
    }
}


void MainWindow::moveEvent(QMoveEvent *)
{
    this->move(QPoint(0,0));
}

void MainWindow::resizeEvent(QResizeEvent *)
{
    this->showMaximized();
}

void MainWindow::proc_finished(int code)
{
    if(proc->exitStatus() == QProcess::NormalExit)
    {
        this->setDisabled(false);
        flag = false;
        QMessageBox::about(this,"info","network restart ok!");
    }
}

 

posted on 2016-04-08 18:40  zengjf  阅读(766)  评论(0编辑  收藏  举报

导航