339 lines
9.6 KiB
C++
339 lines
9.6 KiB
C++
/*
|
|
* Program.cpp
|
|
*
|
|
* Created on: 04.09.2015
|
|
* Author: jdi
|
|
*/
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
|
|
#include "Constant.h"
|
|
#include "Program.h"
|
|
#include "File.h"
|
|
#include "Host.h"
|
|
#include "Socket.h"
|
|
#include "Switch.h"
|
|
#include "Packet.h"
|
|
#include "lookup.h"
|
|
#include "table.h"
|
|
|
|
using namespace std;
|
|
|
|
int printHeader(Packet p) {
|
|
if (options.flags.HEADER) {
|
|
if (options.flags.HEX) {
|
|
cout << "Received Header:\n\t" << p.getHead() << "\n";
|
|
} else {
|
|
p.printHeader();
|
|
printf("\n");
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int printPacket(Packet p) {
|
|
if (options.flags.HEX) {
|
|
cout << "Received Payload:\n\t" << p.getBody() << "\n";
|
|
} else {
|
|
for (dataset d : p.getPayload()) {
|
|
auto lookup = (options.flags.REVERSE) ? snd_lookup : rcv_lookup;
|
|
if (lookup.exists(d.type)) {
|
|
table::set s = lookup[d.type];
|
|
if (d.len > 0) {
|
|
switch (s.format) {
|
|
case table::STRING:
|
|
cout << "+\t" << s.name << " = " << &d.value[0] << "\n";
|
|
break;
|
|
case table::BOOL:
|
|
cout << "+\t" << s.name << " = "
|
|
<< (d.value[0] ? "YES" : "NO") << "\n";
|
|
break;
|
|
case table::HEX:
|
|
cout << "+\t" << s.name << " = " << d.value << "\n";
|
|
break;
|
|
case table::DEC:
|
|
cout << "+\t" << s.name << " = ";
|
|
if (d.value.size() > 0)
|
|
cout << dec << (unsigned) d.value[0];
|
|
for (unsigned i = 1; i < d.value.size(); i++)
|
|
cout << dec << "." << (unsigned) d.value[i];
|
|
cout << "\n";
|
|
break;
|
|
case table::ACTION:
|
|
cout << "Error:" << s.name
|
|
<< " is marked as 'action' but carries payload."
|
|
<< d.value << "\n";
|
|
break;
|
|
default:
|
|
cout << "+\t" << s.name << " = " << d.value << "\n";
|
|
break;
|
|
}
|
|
} else { //empty
|
|
cout << dec << ">\t" << s.name << "\n";
|
|
}
|
|
} else { //unknown id
|
|
if (d.len > 0) {
|
|
cout << "##\t" << d.type << ":\n\t";
|
|
cout << hex << d.value << dec << "\n";
|
|
} else { //empty
|
|
cout << "#>\t" << d.type << "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Program::list() {
|
|
try {
|
|
cout << "List:\n";
|
|
discover([this](Packet a) {
|
|
printHeader(a);
|
|
if (options.flags.HEX) {
|
|
cout <<"Received Payload:\n"<<a.getBody()<<"\n";
|
|
} else {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
File f;
|
|
f.write(sw.toString());
|
|
sw.print();
|
|
}
|
|
return 0;
|
|
});
|
|
io_service->run();
|
|
} catch (exception& e) {
|
|
cerr << "Exception: " << e.what() << "\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Program::sniff() {
|
|
printf("Listening:\n");
|
|
try {
|
|
boost::asio::io_service io_service;
|
|
Socket s(io_service);
|
|
s.setHostIp(host.getIp());
|
|
s.init(DST_PORT, SRC_PORT);
|
|
s.callback = [](Packet p) {
|
|
cout << p.opCodeToString() << "\n";
|
|
printHeader(p);
|
|
printPacket(p);
|
|
return 0;
|
|
};
|
|
s.listen();
|
|
io_service.run();
|
|
} catch (exception& e) {
|
|
cerr << "Exception: " << e.what() << "\n";
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Program::encode(string s) {
|
|
bytes d;
|
|
d = d.readHex(s);
|
|
Packet p = Packet(Packet::NONE);
|
|
p.encode(d);
|
|
cout << d << endl;
|
|
return 0;
|
|
}
|
|
|
|
int Program::setProperty(map<string, string> prop) {
|
|
try {
|
|
datasets data = { };
|
|
for (auto p : prop) {
|
|
string s = p.second;
|
|
dataset d;
|
|
if (rcv_lookup.exists(p.first)) {
|
|
d.type = rcv_lookup.type(p.first);
|
|
if (rcv_lookup[p.first].format == table::STRING) {
|
|
d.len = s.size() + 1;
|
|
d.value = s;
|
|
data.push_back(d);
|
|
}
|
|
}
|
|
}
|
|
|
|
cout << "List:\n";
|
|
discover([this,data](Packet a) {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
sw.print();
|
|
|
|
datasets t = { {SND_PING, 0, {}}};
|
|
get(a, t, [this,data](Packet a) {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
set(a,data,
|
|
|
|
[this](Packet a) {
|
|
cout << a.opCodeToString() << "\n";
|
|
printHeader(a);
|
|
printPacket(a);
|
|
return 0;
|
|
});
|
|
return 0;
|
|
});
|
|
return 0;
|
|
});
|
|
|
|
io_service->run();
|
|
} catch (exception& e) {
|
|
cerr << "Exception: " << e.what() << "\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Program::getProperty(vector<string> prop) {
|
|
try {
|
|
datasets data = { };
|
|
for (string s : prop) {
|
|
dataset d;
|
|
d.type = snd_lookup.type(s);
|
|
data.push_back(d);
|
|
}
|
|
cout << "List:\n";
|
|
discover([this,data](Packet a) {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
sw.print();
|
|
get(a, data, [this](Packet a) {
|
|
cout << a.opCodeToString() << "\n";
|
|
printHeader(a);
|
|
printPacket(a);
|
|
return 0;
|
|
});
|
|
return 0;
|
|
});
|
|
|
|
io_service->run();
|
|
} catch (exception& e) {
|
|
cerr << "Exception: " << e.what() << "\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Program::save() {
|
|
Switch sw = Switch();
|
|
sw.settings.hostname = "testname.lan";
|
|
File f;
|
|
f.write(sw.toString());
|
|
return 0;
|
|
}
|
|
|
|
int Program::restore() {
|
|
File f;
|
|
Switch sw;
|
|
sw.parse(f.read());
|
|
sw.print();
|
|
return 0;
|
|
}
|
|
|
|
int Program::flash() {
|
|
|
|
return 1;
|
|
}
|
|
|
|
int Program::reboot() {
|
|
try {
|
|
discover([this](Packet a) {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
cout <<sw.settings.hostname<<"\t";
|
|
datasets t = { {SND_PING, 0, {}}};
|
|
get(a, t, [this](Packet a) {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
datasets t = { {REBOOT, 1, {options.flags.PERMANENT?(byte)1:(byte)0}}};
|
|
set(a,t,[this](Packet a) {
|
|
if( a.getOpCode()==Packet::CONFIRM)
|
|
cout<< "rebooting now.\n";
|
|
return 0;
|
|
});
|
|
return 0;
|
|
});
|
|
return 0;
|
|
});
|
|
io_service->run();
|
|
} catch (exception& e) {
|
|
cerr << "Exception: " << e.what() << "\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Program::reset() {
|
|
try {
|
|
discover([this](Packet a) {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
cout <<sw.settings.hostname<<"\t";
|
|
datasets t = { {SND_PING, 0, {}}};
|
|
get(a, t, [this](Packet a) {
|
|
datasets d =a.getPayload();
|
|
Switch sw = Switch();
|
|
sw.parse(d);
|
|
datasets t = { {RESET, 0, {}}};
|
|
set(a,t,[this](Packet a) {
|
|
if( a.getOpCode()==Packet::CONFIRM)
|
|
cout<< "reseting config.\n";
|
|
return 0;
|
|
});
|
|
return 0;
|
|
});
|
|
return 0;
|
|
});
|
|
io_service->run();
|
|
} catch (exception& e) {
|
|
cerr << "Exception: " << e.what() << "\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Program::discover(function<int(Packet)> c) {
|
|
Packet p = Packet(Packet::DISCOVERY);
|
|
p.setHostMac(host.getMac());
|
|
p.setPayload( { });
|
|
sock->callback = c;
|
|
sock->send(p);
|
|
return 0;
|
|
}
|
|
|
|
int Program::get(Packet l, datasets t, function<int(Packet)> c) {
|
|
Packet p = Packet(Packet::GET);
|
|
p.setSwitchMac(l.getSwitchMac());
|
|
p.setHostMac(host.getMac());
|
|
p.setPayload(t);
|
|
sock->callback = c;
|
|
sock->send(p);
|
|
return 0;
|
|
}
|
|
|
|
int Program::set(Packet l, datasets t, function<int(Packet)> c) {
|
|
Packet p = Packet(Packet::SET);
|
|
p.setSwitchMac(l.getSwitchMac());
|
|
p.setTokenId(l.getTokenId());
|
|
p.setHostMac(host.getMac());
|
|
bytes n = options.user;
|
|
bytes w = options.password;
|
|
datasets ld = { { LOGIN_USER, (short) (n.size()), n }, { LOGIN_PASSWORD,
|
|
(short) (w.size()), w } };
|
|
p.setPayload(ld + t);
|
|
sock->callback = c;
|
|
sock->send(p);
|
|
return 0;
|
|
}
|
|
|
|
void Program::init() {
|
|
if (options.interface.compare("") == 0)
|
|
options.interface = host.getIface();
|
|
|
|
sock->setHostIp(host.getIp());
|
|
sock->init(DST_PORT, SRC_PORT);
|
|
}
|