diff --git a/src/Host.cpp b/src/Host.cpp index a226ea9..82e220a 100644 --- a/src/Host.cpp +++ b/src/Host.cpp @@ -25,16 +25,16 @@ Host::Host() { } -byteArray<6> Host::getMac() { - byteArray<6> ret = { 0x08, 0x3e, 0x8e, 0x16, 0x17, 0x2c }; +macAddr Host::getMac() { + macAddr ret { { 0x08, 0x3e, 0x8e, 0x16, 0x17, 0x2c } }; //TODO find actual MAC Address return ret; } -byteArray<4> Host::getIp(std::string iface) { +inetAddr Host::getIp(std::string iface) { struct ifaddrs *ifaddr, *ifa; int n; - byteArray<4> data = { 0, 0, 0, 0 }; + inetAddr data { { 0, 0, 0, 0 } }; if (getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); diff --git a/src/Host.h b/src/Host.h index 0160f0c..8772883 100644 --- a/src/Host.h +++ b/src/Host.h @@ -13,8 +13,8 @@ class Host { public: Host(); - byteArray<6> getMac(); - byteArray<4> getIp(std::string); + macAddr getMac(); + inetAddr getIp(std::string); }; #endif /* HOST_H_ */ diff --git a/src/Options.h b/src/Options.h index d1380c5..c5fd8f8 100644 --- a/src/Options.h +++ b/src/Options.h @@ -26,14 +26,18 @@ -p Password\n\ -f --file Not yet implemented:.choose a settings file\n\ -t --timeout Not yet implemented\n\ + -w --wait Not yet implemented: blocking until operation is completed\n\ -s --permanent Not yet implemented: make changes immediately permanent\n\n\ Command Summary:\n\ help This help text\n\ list list all connected switches\n\ sniff capture and display all incoming or outgoing packets\n\ depending on the --reverse option\n\ + encode use encoding algorithm on hex data separated by colon\n\ get Not yet implemented\n\ set Not yet implemented\n\ + save Not yet implemented: save config to file\n\ + restore Not yet implemented: restore onfig from file\n\ flash Not yet implemented: replace firmware\n\ reboot Not yet implemented\n\ reset Not yet implemented\n\n" @@ -41,7 +45,8 @@ #define FLAG_HEX 1 #define FLAG_REVERSE 2 #define FLAG_HEADER 4 -#define FLAG_PERMANENT 4 +#define FLAG_PERMANENT 8 +#define FLAG_WAIT 16 extern Options options; diff --git a/src/Packet.cpp b/src/Packet.cpp index 2c25683..d699726 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -103,7 +103,7 @@ void Packet::setBody(bytes data) { this->body = data; } -void Packet::setHostMac(byteArray<6> mac) { +void Packet::setHostMac(macAddr mac) { this->hostMac = mac; } @@ -127,11 +127,11 @@ void Packet::setSequenceId(short sequenceId) { this->sequenceId = sequenceId; } -const byteArray<6>& Packet::getSwitchMac() const { +macAddr Packet::getSwitchMac() const { return switchMac; } -void Packet::setSwitchMac(byteArray<6> switchMac) { +void Packet::setSwitchMac(macAddr switchMac) { this->switchMac = switchMac; } @@ -187,12 +187,12 @@ void Packet::encode(bytes &data) { t = s[i]; s[i] = s[j]; s[j] = t; - data[k] = ((data[k] ^ s[(s[i] + s[j]) % 256])); + data[k] = data[k] ^ s[(s[i] + s[j]) % 256]; } } void Packet::push(bytes &arr, int &index, byte data) { - if (arr.size() > index) { + if (arr.size() > (unsigned) index) { arr[index++] = data; } else { arr.push_back(data); @@ -200,15 +200,18 @@ void Packet::push(bytes &arr, int &index, byte data) { } } - void Packet::push(bytes &arr, int &index, bytes data) { for (unsigned j = 0; j < data.size(); j++) push(arr, index, data[j]); } -template -void Packet::push(bytes &arr, int &index, byteArray data) { - for (unsigned j = 0; j < N; j++) +void Packet::push(bytes &arr, int &index, inetAddr &data) { + for (unsigned j = 0; j < 4; j++) + push(arr, index, data[j]); +} + +void Packet::push(bytes &arr, int &index, macAddr &data) { + for (unsigned j = 0; j < 6; j++) push(arr, index, data[j]); } @@ -246,10 +249,14 @@ void Packet::pull(bytes &arr, int &index, bytes &ret, unsigned len) { index += len; } -template -void Packet::pull(bytes &arr, int &index, byteArray &ret) { - memcpy(&ret[0], &arr[index], N); - index += N; +void Packet::pull(bytes &arr, int &index, macAddr &ret) { + memcpy(&ret[0], &arr[index], 6); + index += 6; +} + +void Packet::pull(bytes &arr, int &index, inetAddr &ret) { + memcpy(&ret[0], &arr[index], 4); + index += 4; } void Packet::pull(bytes &arr, int &index, short &ret) { diff --git a/src/Packet.h b/src/Packet.h index 20fb956..3413075 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -29,13 +29,13 @@ public: short getLength() const; int getCheckSum() const; short getSequenceId() const; - const byteArray<6>& getSwitchMac() const; + macAddr getSwitchMac() const; const bytes& getBody() const; const bytes& getHead() const; const datasets& getPayload() const; void setBody(bytes); - void setHostMac(byteArray<6>); - void setSwitchMac(byteArray<6>); + void setHostMac(macAddr); + void setSwitchMac(macAddr); void setCheckSum(int); void setSequenceId(short); void setPayload(const datasets& payload); @@ -47,9 +47,9 @@ private: byte version = 1; byte opCode; - byteArray<6> switchMac = { 0, 0, 0, 0, 0, 0 }; - byteArray<6> hostMac = { 0, 0, 0, 0, 0, 0 }; - byteArray<6> broadcastMac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + macAddr switchMac {{ 0, 0, 0, 0, 0, 0 }}; + macAddr hostMac {{ 0, 0, 0, 0, 0, 0 }}; + macAddr broadcastMac {{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }}; short sequenceId; short tokenId = 0; short fragmentOffset = 0; @@ -64,12 +64,16 @@ private: void push(bytes&, int&, int); void push(bytes&, int&, byte); void push(bytes&, int&, bytes); + void push(bytes&, int&, inetAddr&); + void push(bytes&, int&, macAddr&); void push(bytes&, int&, dataset); void pull(bytes&, int&, short&); void pull(bytes&, int&, int&); void pull(bytes&, int&, byte&); void pull(bytes&, int&, bytes&, unsigned); + void pull(bytes&, int&, inetAddr&); + void pull(bytes&, int&, macAddr&); void pull(bytes&, int&, dataset&); }; diff --git a/src/Program.cpp b/src/Program.cpp index 8da3b9d..dff42e5 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -71,13 +71,13 @@ int Program::sniff() { Host h = Host(); Socket s(io_service); s.setHostIp(h.getIp(options.interface)); - s.init(DST_PORT,SRC_PORT); + s.init(DST_PORT, SRC_PORT); s.callback = [](Packet p) { if (options.flags & FLAG_HEADER) { if (options.flags & FLAG_HEX) { - printf("Received Header:\t"); - utils::printHex(p.getHead()); - }else{ + printf("Received Header:\t"); + utils::printHex(p.getHead()); + } else { p.printHeader(); } printf("\n"); @@ -107,29 +107,43 @@ int Program::sniff() { return 1; } -int Program::encode(std::string s){ - std::string delimiter = ":"; - std::string token; - size_t pos = 0; - bytes arr = { }; - int hex; - byte b; - while ((pos = s.find(delimiter)) != std::string::npos) { - token = s.substr(0, pos); - sscanf(token.c_str(), "%x", &hex); - s.erase(0, pos + delimiter.length()); - b = hex & 0xFF; - arr.push_back(b); - } - sscanf(s.c_str(), "%x", &hex); - b = hex & 0xFF; - arr.push_back(b); - +int Program::encode(std::string s) { + bytes d = utils::readHex(s); Packet p = Packet(Packet::DISCOVERY); - p.encode(arr); - printf("%x", arr[0]); - for (unsigned i = 1; i < arr.size(); i++) { - printf(":%x", arr[i]); + p.encode(d); + printf("%x", d[0]); + for (unsigned i = 1; i < d.size(); i++) { + printf(":%x", d[i]); } printf("\n"); + return 0; +} + + +int Program::setProperty(){ + return 0; +} +int Program::getProperty(){ + + return 0; +} +int Program::save(){ + + return 0; +} +int Program::restore(){ + + return 0; +} +int Program::flash(){ + + return 0; +} +int Program::reboot(){ + + return 0; +} +int Program::reset(){ + + return 0; } diff --git a/src/Program.h b/src/Program.h index be7207a..265afbe 100644 --- a/src/Program.h +++ b/src/Program.h @@ -21,6 +21,13 @@ public: int list(); int sniff(); int encode(std::string); + int setProperty(); + int getProperty(); + int save(); + int restore(); + int flash(); + int reboot(); + int reset(); }; #endif /* PROGRAM_H_ */ diff --git a/src/Socket.cpp b/src/Socket.cpp index 3abd14b..2aa3f47 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -31,7 +31,7 @@ void Socket::init(short dst_port, short src_port) { } printf("IP:\t"); - utils::printDec(local_ip); + utils::print(local_ip); printf("\n"); wildcard_endpoint_ = asio::ip::udp::endpoint( @@ -53,7 +53,7 @@ void Socket::init(short dst_port, short src_port) { } -void Socket::setHostIp(bytes ip) { +void Socket::setHostIp(inetAddr ip) { local_ip=ip; } diff --git a/src/Socket.h b/src/Socket.h index 513dad6..1f6a42b 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -22,7 +22,7 @@ public: void init(short, short); void send(bytes); void listen(); - void setHostIp(bytes); + void setHostIp(inetAddr); int (*callback)(Packet)=[](Packet a) { return 0; }; @@ -36,7 +36,7 @@ private: asio::ip::udp::endpoint wildcard_endpoint_; asio::ip::udp::endpoint local_endpoint_; bytes data = bytes(MAX_LENGTH); - byteArray<4> local_ip = bytes(4); + inetAddr local_ip; }; diff --git a/src/Switch.h b/src/Switch.h index 94828c0..e0c8d17 100644 --- a/src/Switch.h +++ b/src/Switch.h @@ -37,16 +37,16 @@ private: std::string type; std::string hardware_version; std::string firmware_version; - byteArray<6> mac; + macAddr mac; } device; struct { std::string password = DEFAULT_PASS; std::string username = DEFAULT_USER; struct { std::string hostname; - byteArray<4> ip_addr; - byteArray<4> ip_mask; - byteArray<4> gateway; + inetAddr ip_addr; + inetAddr ip_mask; + inetAddr gateway; byte dhcp; } network; } settings; diff --git a/src/Types.h b/src/Types.h index 54008b2..4f0f275 100644 --- a/src/Types.h +++ b/src/Types.h @@ -29,8 +29,9 @@ std::vector &operator+=(std::vector &A, const std::vector &B) { return A; } -template -using byteArray = std::array; +typedef std::array macAddr; +typedef std::array inetAddr; + typedef std::vector bytes; typedef unsigned char byte; diff --git a/src/Utils.h b/src/Utils.h index 334bec3..fcf7217 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -14,6 +14,26 @@ namespace utils { +static bytes readHex(std::string d) { + std::string delimiter = ":"; + std::string token; + size_t pos = 0; + bytes arr = { }; + int hex; + byte b; + while ((pos = d.find(delimiter)) != std::string::npos) { + token = d.substr(0, pos); + sscanf(token.c_str(), "%x", &hex); + d.erase(0, pos + delimiter.length()); + b = hex & 0xFF; + arr.push_back(b); + } + sscanf(d.c_str(), "%x", &hex); + b = hex & 0xFF; + arr.push_back(b); + return arr; +} + static void printHex(bytes d) { if (d.size() > 0) printf("%.2X", d[0]); @@ -22,14 +42,14 @@ static void printHex(bytes d) { } } -static void print(byteArray<6> d) { +static void print(macAddr d) { printf("%.2X", d[0]); for (unsigned i = 1; i < 6; i++) { printf(":%.2X", d[i]); } } -static void print(byteArray<4> d) { +static void print(inetAddr d) { printf("%.1d", d[0]); for (unsigned i = 1; i < 4; i++) { printf(".%.1d", d[i]); diff --git a/src/smrtlink.cpp b/src/smrtlink.cpp index ccc27bd..0e42e09 100644 --- a/src/smrtlink.cpp +++ b/src/smrtlink.cpp @@ -3,7 +3,7 @@ // Author : jdi // Version : // Copyright : GPL v2 -// Description : Hello World in C++, Ansi-style +// Description : SmrtLink in C++, Ansi-style //============================================================================ #include @@ -25,6 +25,10 @@ Options options; +constexpr unsigned int caseArg(const char* str, int h = 0) { + return !str[h] ? 5381 : (caseArg(str, h + 1) * 33) ^ str[h]; +} + int main(int argc, char *argv[]) { int opt, index; @@ -35,7 +39,8 @@ int main(int argc, char *argv[]) { required_argument, 0, 'u' }, { "interface", required_argument, 0, 'i' }, { "header", required_argument, 0, 'b' }, { "hex", required_argument, 0, 'x' }, { "file", required_argument, 0, 'f' }, { "timeout", - required_argument, 0, 't' }, { 0, 0, 0, 0 }, }; + required_argument, 0, 't' }, { "wait", + required_argument, 0, 'w' }, { 0, 0, 0, 0 }, }; Program p = Program(); @@ -71,6 +76,10 @@ int main(int argc, char *argv[]) { options.flags |= FLAG_PERMANENT; break; + case 'w': + options.flags |= FLAG_WAIT; + break; + case 't': options.timeout = atoi(optarg); break; @@ -105,29 +114,31 @@ int main(int argc, char *argv[]) { } if (optind < argc) { - if (strcmp(argv[optind], "help") == 0) { - fprintf(stderr, VERSION); - fprintf(stderr, USAGE, argv[0]); - fprintf(stderr, HELP); - exit(EXIT_SUCCESS); - } else if (strcmp(argv[optind], "get") == 0 - || strcmp(argv[optind], "set") == 0 - || strcmp(argv[optind], "reboot") == 0 - || strcmp(argv[optind], "reset") == 0 - || strcmp(argv[optind], "flash") == 0) { - optind++; + std::string cmd = std::string(argv[optind++]); + + switch (caseArg(cmd.c_str())) { + case caseArg("get"): + case caseArg("set"): + case caseArg("reboot"): + case caseArg("reset"): + case caseArg("save"): + case caseArg("restore"): + case caseArg("flash"): fprintf(stderr, "Not yet implemented.\n"); exit(EXIT_FAILURE); - } else if (strcmp(argv[optind], "list") == 0) { - optind++; + break; + + case caseArg("list"): if (p.list()) exit(EXIT_SUCCESS); - } else if (strcmp(argv[optind], "sniff") == 0) { - optind++; + break; + + case caseArg("sniff"): if (p.sniff()) exit(EXIT_SUCCESS); - } else if (strcmp(argv[optind], "encode") == 0) { - optind++; + break; + + case caseArg("encode"): if (optind < argc) { std::string s(argv[optind]); optind++; @@ -137,7 +148,16 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Argument expected after encode\n"); exit(EXIT_FAILURE); } - } else { + break; + + case caseArg("help"): + fprintf(stderr, VERSION); + fprintf(stderr, USAGE, argv[0]); + fprintf(stderr, HELP); + exit(EXIT_SUCCESS); + break; + + default: printf("Unknown command: %s\n", argv[optind]); optind++; while (optind < argc) { @@ -148,6 +168,5 @@ int main(int argc, char *argv[]) { } } exit(EXIT_FAILURE); - }