/**********************************************************************
* 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()>)
{
//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 = ;
foreach(QString s,sl)
{
r <<= ;
r |= s.toUInt();
}
return r;
}
/**
* @brief int2ip
* @param ip
* @return
*
* 将int型整数,转化成点分十进制IP
*/
QString int2ip(unsigned int ip)
{
return QString::number((ip >> ) & 0xff) + "." + QString::number((ip >> ) & 0xff)
+ "." + QString::number((ip >> ) & 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();
}
}
void MainWindow::moveEvent(QMoveEvent *)
{
this->move(QPoint(,));
}
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!");
}
}