From da8ac53f7d9bae432510b0ae7595f8affa8803d3 Mon Sep 17 00:00:00 2001 From: /jdi/ Date: Thu, 15 Oct 2015 20:31:47 +0200 Subject: [PATCH] json lib added --- src/Host.cpp | 29 ++++-- src/Host.h | 2 +- src/Lookup.h | 2 +- src/Options.h | 35 ++++--- src/Packet.cpp | 2 +- src/Packet.h | 2 +- src/Program.cpp | 15 ++- src/Program.h | 2 +- src/Socket.cpp | 7 +- src/Socket.h | 2 +- src/Switch.cpp | 211 +++++++++++++++++++++++++++++++++++--- src/Switch.h | 36 ++++++- src/Types/Types.h | 111 -------------------- src/Types/bytes.cpp | 28 ----- src/Types/bytes.h | 86 ---------------- src/Types/datasets.cpp | 8 -- src/Types/datasets.h | 31 ------ src/Types/lookupTable.cpp | 10 -- src/Types/lookupTable.h | 42 -------- src/smrtlink.cpp | 16 ++- 20 files changed, 300 insertions(+), 377 deletions(-) delete mode 100644 src/Types/Types.h delete mode 100644 src/Types/bytes.cpp delete mode 100644 src/Types/bytes.h delete mode 100644 src/Types/datasets.cpp delete mode 100644 src/Types/datasets.h delete mode 100644 src/Types/lookupTable.cpp delete mode 100644 src/Types/lookupTable.h diff --git a/src/Host.cpp b/src/Host.cpp index 57372e9..a625cf9 100644 --- a/src/Host.cpp +++ b/src/Host.cpp @@ -23,18 +23,20 @@ #include "Options.h" #include "Host.h" -#include "Types/Types.h" +#include "Types.h" macAddr Host::getMac() { - int s; - struct ifreq buffer; + int s; + struct ifreq buffer; macAddr data { 0, 0, 0, 0, 0, 0 }; - s = socket(PF_INET, SOCK_DGRAM, 0); - memset(&buffer, 0x00, sizeof(buffer)); - strcpy(buffer.ifr_name, options.interface.c_str()); - ioctl(s, SIOCGIFHWADDR, &buffer); - close(s); - memcpy(&data[0], &buffer.ifr_hwaddr.sa_data[0], 6); + if (options.interface != "") { + s = socket(PF_INET, SOCK_DGRAM, 0); + memset(&buffer, 0x00, sizeof(buffer)); + strcpy(buffer.ifr_name, options.interface.c_str()); + ioctl(s, SIOCGIFHWADDR, &buffer); + close(s); + memcpy(&data[0], &buffer.ifr_hwaddr.sa_data[0], 6); + } return data; } @@ -55,6 +57,15 @@ ipAddr Host::getIp() { return data; } } + for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { + if (ifa->ifa_addr == NULL) + continue; + if (ifa->ifa_addr->sa_family == AF_INET) + if (getIface().compare(ifa->ifa_name) == 0) { + memcpy(&data[0], &ifa->ifa_addr->sa_data[2], 4); + return data; + } + } freeifaddrs(ifaddr); return data; } diff --git a/src/Host.h b/src/Host.h index 7387804..3e7f09f 100644 --- a/src/Host.h +++ b/src/Host.h @@ -8,7 +8,7 @@ #ifndef HOST_H_ #define HOST_H_ -#include "Types/Types.h" +#include "Types.h" class Host { public: diff --git a/src/Lookup.h b/src/Lookup.h index e41b66c..add7ecc 100644 --- a/src/Lookup.h +++ b/src/Lookup.h @@ -5,7 +5,7 @@ * Author: jdi */ -#include "Types/lookupTable.h" +#include "lookupTable.h" static lookupTable rcv_lookup = { { 1, "type" }, //string { 2, "hostname" }, //string diff --git a/src/Options.h b/src/Options.h index c59a0e5..a5484a4 100644 --- a/src/Options.h +++ b/src/Options.h @@ -8,26 +8,27 @@ #ifndef OPTIONS_H_ #define OPTIONS_H_ -#include "Types/Types.h" +#include "Types.h" #define VERSION "smrtlink (v1 Linux)\n" -#define USAGE "usage: %s [-bhrvx] [-i interface] [-u [password:]username]\n\ +#define USAGE "usage: %s [-bdhrvswx] [-i interface] [-u [password:]username]\n\ [-p password] \n\n" #define HELP "\ - ### for questions please contact ###\n\ Option Summary:\n\ - -h --help This help text\n\ - -v --version Display version of this tool\n\ - -r switch ports to emulate switch while sniffing\n\ - -b --header Show header\n\ - -x --hex Display Packets as Hex String\n\ - -i --interface only use one Interface\n\ - -u --user Login with user\n\ - -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\ + -h --help This help text\n\ + -v --version Display version of this tool\n\ + -d --debug [n] Show debugging messages\n\ + -r switch ports to emulate switch while sniffing\n\ + -b --header Show header\n\ + -x --hex Display Packets as Hex String\n\ + -i --interface only use one Interface\n\ + -u --user <[password:]username>\n\ + -p --password \n\ + Login with Username and 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\ @@ -40,13 +41,15 @@ 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" + reset Not yet implemented\n\n\ + ### for questions please contact ###\n\n" #define FLAG_HEX 1 #define FLAG_REVERSE 2 #define FLAG_HEADER 4 #define FLAG_PERMANENT 8 #define FLAG_WAIT 16 +#define FLAG_DEBUG 32 extern Options options; diff --git a/src/Packet.cpp b/src/Packet.cpp index 9b0aa66..db4cf4c 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -9,7 +9,7 @@ #include #include #include "Packet.h" -#include "Types/Types.h" +#include "Types.h" Packet::Packet(OpCode c) { srand(time(NULL)); diff --git a/src/Packet.h b/src/Packet.h index 93d96e9..6dd7b13 100644 --- a/src/Packet.h +++ b/src/Packet.h @@ -11,7 +11,7 @@ #define HEADER_LEN 32 #define PACKET_END 0xFFFF0000 -#include "Types/Types.h" +#include "Types.h" class Packet { public: diff --git a/src/Program.cpp b/src/Program.cpp index e173b09..ab20353 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -17,7 +17,7 @@ int Program::list() { - printf("List:\n"); + std::cout << "List:\n"; Packet p = Packet(Packet::DISCOVERY); p.setHostMac(host.getMac()); p.setPayload( { }); @@ -162,12 +162,21 @@ int Program::getProperty() { return 1; } int Program::save() { + Switch sw = Switch(); + std::string str = sw.toString(); //File = fopen(otions.file) + return 0; } int Program::restore() { + + const char str[] = + " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } "; + printf("Original JSON:\n %s\n", str); + Switch sw = Switch(); + sw.parse(str); //File = fopen(otions.file) - return 0; + return 1; } int Program::flash() { @@ -182,6 +191,6 @@ int Program::reset() { return 0; } void Program::init() { - if(options.interface.compare("")==0) + if (options.interface.compare("") == 0) options.interface = host.getIface(); } diff --git a/src/Program.h b/src/Program.h index 4e7e84e..bb2e7e3 100644 --- a/src/Program.h +++ b/src/Program.h @@ -8,7 +8,7 @@ #ifndef PROGRAM_H_ #define PROGRAM_H_ -#include "Types/Types.h" +#include "Types.h" #include "Host.h" class Program { diff --git a/src/Socket.cpp b/src/Socket.cpp index 9357ee0..0e1da69 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -15,7 +15,7 @@ #include "Packet.h" #include "Options.h" #include "Host.h" -#include "Types/Types.h" +#include "Types.h" Socket::Socket(asio::io_service& io_service) : send_socket_(io_service), receive_socket_(io_service) { @@ -29,7 +29,8 @@ void Socket::init(short dst_port, short src_port) { src_port = p; } - std::cout <<"IP:\t"< #include "Packet.h" -#include "Types/Types.h" +#include "Types.h" #define SRC_PORT 29809 #define DST_PORT 29808 diff --git a/src/Switch.cpp b/src/Switch.cpp index e693c59..fae577d 100644 --- a/src/Switch.cpp +++ b/src/Switch.cpp @@ -6,33 +6,212 @@ */ #include -#include "Types/Types.h" +#include "Types.h" #include "Switch.h" #include "Lookup.h" #include "Options.h" -void Switch::parse(datasets arr) { - device.type = arr[1].value; - settings.hostname = arr[2].value; - device.mac = arr[3].value; - settings.ip_addr = arr[4].value; - settings.ip_mask = arr[5].value; - settings.gateway = arr[6].value; - device.firmware_version = arr[7].value; - device.hardware_version = arr[8].value; - settings.dhcp = arr[9].value[0]; +int Switch::parse(datasets arr) { + for (auto a : arr) { + parse(a.second); + } + return 0; } -void Switch::parse(dataset d) { +int Switch::parse(dataset d) { auto lookup = (options.flags & FLAG_REVERSE) ? snd_lookup : rcv_lookup; - if(d.type==lookup["type"]){ + if (d.type == lookup["type"]) { device.type = d.value; } - if(d.type==lookup["mac"]){ + if (d.type == lookup["mac"]) { device.mac = d.value; } - if(d.type==lookup["type"]){ - device.type = d.value; + if (d.type == lookup["firmware_version"]) { + device.firmware_version = d.value; } + if (d.type == lookup["hardware_version"]) { + device.hardware_version = d.value; + } + if (d.type == lookup["hostname"]) { + settings.hostname = d.value; + } + if (d.type == lookup["ip_addr"]) { + settings.ip_addr = d.value; + } + if (d.type == lookup["ip_mask"]) { + settings.ip_mask = d.value; + } + if (d.type == lookup["gateway"]) { + settings.gateway = d.value; + } + if (d.type == lookup["dhcp"]) { + settings.dhcp = d.value[0]; + } + return 0; } +int Switch::parse(std::string str) { + + if (json.Parse(str.c_str()).HasParseError()) + return 1; + if (options.flags & FLAG_DEBUG) + std::cout<<"\nParsing to document succeeded.\n"; + + + + + + + + + + + + + + + + + + + + + + + + + //////////////////////////////////////////////////////////////////////////// + // 2. Access values in document. + + printf("\nAccess values in document:\n"); + assert(json.IsObject()); // Document is a JSON value represents the root of DOM. Root can be either an object or array. + + assert(json.HasMember("hello")); + assert(json["hello"].IsString()); + printf("hello = %s\n", json["hello"].GetString()); + + // Since version 0.2, you can use single lookup to check the existing of member and its value: + rapidjson::Value::MemberIterator hello = json.FindMember("hello"); + assert(hello != json.MemberEnd()); + assert(hello->value.IsString()); + assert(strcmp("world", hello->value.GetString()) == 0); + (void)hello; + + assert(json["t"].IsBool()); // JSON true/false are bool. Can also uses more specific function IsTrue(). + printf("t = %s\n", json["t"].GetBool() ? "true" : "false"); + + assert(json["f"].IsBool()); + printf("f = %s\n", json["f"].GetBool() ? "true" : "false"); + + printf("n = %s\n", json["n"].IsNull() ? "null" : "?"); + + assert(json["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type. + assert(json["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true. + printf("i = %d\n", json["i"].GetInt()); // Alternative (int)document["i"] + + assert(json["pi"].IsNumber()); + assert(json["pi"].IsDouble()); + printf("pi = %g\n", json["pi"].GetDouble()); + + { + const rapidjson::Value& a = json["a"]; // Using a reference for consecutive access is handy and faster. + assert(a.IsArray()); + for (rapidjson::SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t. + printf("a[%d] = %d\n", i, a[i].GetInt()); + + int y = a[0].GetInt(); + (void)y; + + // Iterating array with iterators + printf("a = "); + for (rapidjson::Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + printf("%d ", itr->GetInt()); + printf("\n"); + } + + // Iterating object members + static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" }; + for (rapidjson::Value::ConstMemberIterator itr = json.MemberBegin(); itr != json.MemberEnd(); ++itr) + printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]); + + + + return 0; +} + +std::string Switch::toString() { + //////////////////////////////////////////////////////////////////////////// + // 3. Modify values in document. + + // Change i to a bigger number + { + uint64_t f20 = 1; // compute factorial of 20 + for (uint64_t j = 1; j <= 20; j++) + f20 *= j; + json["i"] = f20; // Alternate form: document["i"].SetUint64(f20) + assert(!json["i"].IsInt()); // No longer can be cast as int or uint. + } + + // Adding values to array. + { + rapidjson::Value& a = json["a"]; // This time we uses non-const reference. + rapidjson::Document::AllocatorType& allocator = json.GetAllocator(); + for (int i = 5; i <= 10; i++) + a.PushBack(i, allocator); // May look a bit strange, allocator is needed for potentially realloc. We normally uses the document's. + + // Fluent API + a.PushBack("Lua", allocator).PushBack("Mio", allocator); + } + + // Making string values. + + // This version of SetString() just store the pointer to the string. + // So it is for literal and string that exists within value's life-cycle. + { + json["hello"] = "hostname"; //settings.hostname; // This will invoke strlen() + // Faster version: + // document["hello"].SetString("rapidjson", 9); + } + + // This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer. + rapidjson::Value author; + { + char buffer[10]; + int len = sprintf(buffer, "%s %s", "Milo", "Yip"); // synthetic example of dynamically created string. + + author.SetString(buffer, static_cast(len), json.GetAllocator()); + // Shorter but slower version: + // document["hello"].SetString(buffer, document.GetAllocator()); + + // Constructor version: + // Value author(buffer, len, document.GetAllocator()); + // Value author(buffer, document.GetAllocator()); + memset(buffer, 0, sizeof(buffer)); // For demonstration purpose. + } + // Variable 'buffer' is unusable now but 'author' has already made a copy. + json.AddMember("author", author, json.GetAllocator()); + + assert(author.IsNull()); // Move semantic for assignment. After this variable is assigned as a member, the variable becomes null. + + + + + + + + + + + + + + + + std::cout<<"\nModified JSON with reformatting:\n"; + rapidjson::StringBuffer sb; + rapidjson::PrettyWriter writer(sb); + json.Accept(writer); // Accept() traverses the DOM and generates Handler events. + return sb.GetString(); +} + + diff --git a/src/Switch.h b/src/Switch.h index 2daa2c2..5a7ede2 100644 --- a/src/Switch.h +++ b/src/Switch.h @@ -10,11 +10,38 @@ #include #include -#include "Types/Types.h" +#include "../include/rapidjson/document.h" +#include "../include/rapidjson/prettywriter.h" +#include "Types.h" #define DEFAULT_USER "admin" #define DEFAULT_PASS "admin" +typedef rapidjson::Value jsonNode; + +/* +template +jsonNode to_json(const T &x) { + // TODO Throw undefined + return NULL; +} + +template<> jsonNode to_json(const vlan &x) { + jsonNode ret; + return ret; +} + +template +T from_json(const jsonNode &s) { +// TODO Throw not implemented + return NULL; +} + +template<> vlan from_json(const jsonNode &s) { + vlan ret; + return ret; +}*/ + struct vlan { int vlan_id; std::string name; @@ -34,8 +61,10 @@ class Switch { public: Switch() { } - void parse(datasets); - void parse(dataset); + int parse(datasets); + int parse(dataset); + int parse(std::string); + std::string toString(); struct { std::string type; std::string hardware_version; @@ -52,6 +81,7 @@ public: bool dhcp; } settings; private: + rapidjson::Document json; std::vector vlans; std::vector ports; }; diff --git a/src/Types/Types.h b/src/Types/Types.h deleted file mode 100644 index 8822db9..0000000 --- a/src/Types/Types.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Types.h - * - * Created on: 11.09.2015 - * Author: jdi - */ - -#ifndef TYPES_H_ -#define TYPES_H_ - -#include -#include -#include -#include -#include -#include - -#include "bytes.h" -#include "datasets.h" - -class macAddr: public std::array { -public: - friend std::ostream& operator<<(std::ostream& out, const macAddr& arr) { - out << std::hex << std::setw(2) << std::setfill('0') - << (unsigned) arr[0]; - for (unsigned i = 1; i < 6; i++) { - out << ":" << std::setw(2) << std::setfill('0') - << (unsigned) arr[i]; - } - return out; - } - - macAddr() { - *this= {0,0,0,0,0,0}; - } - - macAddr(std::initializer_list s) { - int i = 0; - for (byte b : s) { - if(i<6) (*this)[i++]=b; - else break; - } - } - - macAddr(bytes bts) { - int i = 0; - for (byte b : bts) { - if(i<6) (*this)[i++]=b; - else break; - } - } -}; - -class ipAddr: public std::array { -public: - - ipAddr() { - *this= {0,0,0,0,0,0}; - } - - ipAddr(std::initializer_list s) { - int i = 0; - for (byte b : s) { - if(i<4) (*this)[i++]=b; - else break; - } - } - - ipAddr(bytes bts) { - int i = 0; - for (byte b : bts) { - if(i<4) (*this)[i++]=b; - else break; - } - } - - friend std::ostream& operator<<(std::ostream& out, ipAddr& arr) { - out << std::dec << (unsigned) arr[0]; - for (unsigned i = 1; i < 4; i++) { - out << "." << (unsigned) arr[i]; - } - return out; - } -}; - -template -std::vector operator+(const std::vector &A, const std::vector &B) { - std::vector AB; - AB.reserve(A.size() + B.size()); // preallocate memory - AB.insert(AB.end(), A.begin(), A.end()); // add A; - AB.insert(AB.end(), B.begin(), B.end()); // add B; - return AB; -} - -template -std::vector &operator+=(std::vector &A, const std::vector &B) { - A.reserve(A.size() + B.size()); - A.insert(A.end(), B.begin(), B.end()); - return A; -} - -struct Options { - unsigned flags = 0x00; - std::string user; - std::string password; - std::string interface; - std::string file; - long timeout; -}; - -#endif /* TYPES_H_ */ diff --git a/src/Types/bytes.cpp b/src/Types/bytes.cpp deleted file mode 100644 index bdc8c9d..0000000 --- a/src/Types/bytes.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Bytes.cpp - * - * Created on: 02.10.2015 - * Author: jdi - */ - -#include "bytes.h" - -bytes::bytes(std::string d) { - vector(); - std::string delimiter = ":"; - std::string token; - size_t pos = 0; - int hex; - byte b; - resize(0); - 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; - push_back(b); - } - sscanf(d.c_str(), "%x", &hex); - b = hex & 0xFF; - push_back(b); -} diff --git a/src/Types/bytes.h b/src/Types/bytes.h deleted file mode 100644 index dcc0ec9..0000000 --- a/src/Types/bytes.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Bytes.h - * - * Created on: 02.10.2015 - * Author: jdi - */ - -#ifndef BYTES_H_ -#define BYTES_H_ - -#include -#include -#include -#include -#include -#include -#include - -typedef unsigned char byte; - -class bytes: public std::vector { - typedef std::vector vector; -public: - using vector::operator[]; - bytes() { - } - bytes(int n) : - vector(n) { - } - - bytes(std::string); - - bytes(std::initializer_list s) - { - for (uint8_t b : s) { - this->push_back(b); - } - } - - bytes(const vector &B) { - this->reserve(B.size()); - this->insert(this->begin(), B.begin(), B.end()); - } - - bytes readHex(std::string s){ - return bytes(s); - } - - bytes operator=(const vector &B) { - this->reserve(B.size()); - this->insert(this->begin(), B.begin(), B.end()); - return *this; - } - - bytes &operator+=(const bytes &B) { - this->reserve(this->size() + B.size()); - this->insert(this->end(), B.begin(), B.end()); - return *this; - } - - bytes operator+(const bytes &B) { - bytes AB; - AB.reserve(this->size() + B.size()); - AB.insert(AB.end(), this->begin(), this->end()); - AB.insert(AB.end(), B.begin(), B.end()); - return AB; - } - - friend std::ostream& operator<<(std::ostream& out, const bytes& arr) { - if (arr.size() > 0) { - out << std::hex << std::setw(2) << std::setfill('0') - << (unsigned) arr[0]; - } - for (unsigned i = 1; i < arr.size(); i++) { - out << ":" << std::setw(2) << std::setfill('0') << (unsigned) arr[i]; - } - return out; - } - - operator std::string() { - std::string s(this->begin(),this->end()); - return s; - } -}; - -#endif /* BYTES_H_ */ diff --git a/src/Types/datasets.cpp b/src/Types/datasets.cpp deleted file mode 100644 index 63529b4..0000000 --- a/src/Types/datasets.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Datasets.cpp - * - * Created on: 02.10.2015 - * Author: jdi - */ - -#include "datasets.h" diff --git a/src/Types/datasets.h b/src/Types/datasets.h deleted file mode 100644 index e570b18..0000000 --- a/src/Types/datasets.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Datasets.h - * - * Created on: 02.10.2015 - * Author: jdi - */ - -#ifndef DATASETS_H_ -#define DATASETS_H_ - -#include -#include "bytes.h" - -struct dataset { - short type; - short len; - bytes value; -}; - -class datasets : public std::map { -public: - datasets(){}; - datasets(std::initializer_list s) - { - for (dataset b : s) { - (*this)[b.type]=b; - } - } -}; - -#endif /* DATASETS_H_ */ diff --git a/src/Types/lookupTable.cpp b/src/Types/lookupTable.cpp deleted file mode 100644 index eba7f6c..0000000 --- a/src/Types/lookupTable.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * lookupTable.cpp - * - * Created on: 11.10.2015 - * Author: jdi - */ - -#include "lookupTable.h" - - diff --git a/src/Types/lookupTable.h b/src/Types/lookupTable.h deleted file mode 100644 index 1c6e5c3..0000000 --- a/src/Types/lookupTable.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * lookupTable.h - * - * Created on: 11.10.2015 - * Author: jdi - */ - -#ifndef LOOKUPTABLE_H_ -#define LOOKUPTABLE_H_ - -#include - -class lookupTable { - struct set { - short n; - std::string s; - }; -public: - lookupTable(std::initializer_list l) { - for (set s : l) { - this->left[s.n] = s.s; - this->right[s.s] = s.n; - } - } - const short& operator[](std::string s) { - return this->right[s]; - } - const std::string& operator[](short n) { - return this->left[n]; - } - bool exists(std::string s) { - return !(right.find(s) == right.end()); - } - bool exists(short n) { - return !(left.find(n) == left.end()); - } -private: - std::map left; - std::map right; -}; - -#endif /* LOOKUPTABLE_H_ */ diff --git a/src/smrtlink.cpp b/src/smrtlink.cpp index 971241b..e8f8984 100644 --- a/src/smrtlink.cpp +++ b/src/smrtlink.cpp @@ -34,8 +34,8 @@ int main(int argc, char *argv[]) { const struct option longopts[] = { { "version", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, { "reverse", no_argument, 0, 'r' }, { - "permanent", no_argument, 0, 's' }, { "password", required_argument, - 0, 'p' }, { "user", + "permanent", no_argument, 0, 's' }, { "debug", optional_argument, 0, + 'd' }, { "password", required_argument, 0, 'p' }, { "user", 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", @@ -44,8 +44,8 @@ int main(int argc, char *argv[]) { Program p = Program(); - while ((opt = getopt_long(argc, argv, "bhrsvxp:u:i:f:t:", longopts, &index)) - != -1) { + while ((opt = getopt_long(argc, argv, "bhrvswxp:u:i:f:t:d::", longopts, + &index)) != -1) { switch (opt) { case 'h': @@ -80,8 +80,14 @@ int main(int argc, char *argv[]) { options.flags |= FLAG_WAIT; break; + case 'd': + options.flags |= FLAG_DEBUG; + if (optarg != NULL) + options.debug_level = atoi(optarg); + break; + case 't': - options.timeout = atoi(optarg); + options.timeout = atol(optarg); break; case 'f':