diff --git a/Bytes.cpp b/Bytes.cpp new file mode 100644 index 0000000..b26247f --- /dev/null +++ b/Bytes.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + * By Théophile Bastian, 2017 + * M1 Network course project at ENS Cachan, Juliusz Chroboczek. + * License: WTFPL v2 + **************************************************************************/ + +/*************************************************************************** + * Reused from a former project, by Théophile Bastian & Nathanaël Courant + * git@github.com:tobast/sysres-pikern.git + **************************************************************************/ + +#include "Bytes.h" +#include +#include +using namespace std; + +Bytes::Bytes() : data(), firstIndex(0) {} + +Bytes::Bytes(const void* buff, size_t len) : data(), firstIndex(0) { + data.reserve(len); + for(size_t pos=0; pos < len; pos++) + data.push_back(((u8*)buff)[pos]); +} + +u8& Bytes::operator[](const size_t pos) { + if(pos < size()) + return data[pos+firstIndex]; + throw OutOfRange(); +} + +u8 Bytes::operator[](const size_t pos) const { + if(pos < size()) + return data[pos+firstIndex]; + throw OutOfRange(); +} +u16 Bytes::ushortAt(const size_t pos) const { + if(pos+1 < size()) + return (((u16)data[pos+firstIndex+1])<<8)+data[pos+firstIndex]; + throw OutOfRange(); +} + +size_t Bytes::size() const { + return data.size() - firstIndex; +} + +Bytes& Bytes::operator<<(char v) { + insertData(v); + return *this; +} +Bytes& Bytes::operator<<(u8 v) { + insertData(v); + return *this; +} +Bytes& Bytes::operator<<(u16 v) { + insertData(v); + return *this; +} +Bytes& Bytes::operator<<(u32 v) { + insertData(v); + return *this; +} +Bytes& Bytes::operator<<(const Bytes& v) { + data.reserve(data.size() + v.size()); + for(size_t byte=0; byte < v.size(); byte++) + data.push_back(v[byte]); + return *this; +} +Bytes& Bytes::operator<<(const char* str) { + unsigned len = strlen(str); + data.reserve(data.size() + len); + for(unsigned byte=0; byte < len; byte++) + data.push_back(str[byte]); + return *this; +} + +Bytes& Bytes::operator>>(u8& v) { + extractData(v); + return *this; +} +Bytes& Bytes::operator>>(u16& v) { + extractData(v); + return *this; +} +Bytes& Bytes::operator>>(u32& v) { + extractData(v); + return *this; +} +Bytes& Bytes::operator>>(char& v) { + extractData(v); + return *this; +} + +void Bytes::operator=(const Bytes& oth) { + firstIndex=0; + data.clear(); + data.reserve(oth.size()); + for(size_t pos=0; pos < oth.size(); pos++) + data.push_back(oth[pos]); +} + +Bytes Bytes::sub(size_t beg, size_t len) const { + if(beg+len >= size()) + throw OutOfRange(); + Bytes out; + for(size_t byte=0; byte < len; byte++) + out << (*this)[byte+beg]; + return out; +} + +void Bytes::writeToBuffer(void* buff, unsigned maxLen) const { + if(maxLen == 0) + maxLen = size(); + for(size_t pos=0; pos < min((size_t)maxLen, size()); pos++) + ((u8*)buff)[pos] = (*this)[pos]; +} + +char charOfDigit(u8 dig) { + if(dig < 10) + return dig+'0'; + return dig+'A'-10; +} +void hexdumpByte(Bytes& dest, u8 b) { + dest << charOfDigit(b/16) << charOfDigit(b & 0xf); +} + +void Bytes::hexdump(Bytes& dest) const { + for(unsigned pos=0; pos < size(); pos++) { + hexdumpByte(dest, (*this)[pos]); + if(pos % 32 == 31) + dest << '\n'; + else if(pos % 4 == 3) + dest << ' '; + } + if(size() % 32 != 0) + dest << '\n'; +} + +template void Bytes::extractData(T& v) { + if(size() < sizeof(v)) + throw OutOfRange(); + for(size_t byte=0; byte < sizeof(v); byte++) + v = (v<<8) | data[firstIndex+byte]; + firstIndex += sizeof(v); +} + +template void Bytes::insertData(T v) { + for(int byte=sizeof(v)-1; byte >= 0; byte--) { + data.push_back((u8) (v >> (8*byte))); + } +} + diff --git a/Bytes.h b/Bytes.h new file mode 100644 index 0000000..ca3436f --- /dev/null +++ b/Bytes.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * By Théophile Bastian, 2017 + * M1 Network course project at ENS Cachan, Juliusz Chroboczek. + * License: WTFPL v2 + **************************************************************************/ + +/*************************************************************************** + * Reused from a former project, by Théophile Bastian & Nathanaël Courant + * git@github.com:tobast/sysres-pikern.git + **************************************************************************/ + +#pragma once + +#include +#include +#include + +#include "data.h" + +class Bytes { + public: + class OutOfRange : public std::exception {}; + /// Exception -- thrown by operator[] + + Bytes(); + Bytes(const void* buff, size_t len); + /// Initializes the object with [buff], reading [len] bytes. + + u8& operator[](const size_t pos); + u8 operator[](const size_t pos) const; + /// Accesses the [pos]th element. Throws OutOfRange if pos >= size() + + u16 ushortAt(const size_t pos) const; + /// Accesses the 16 bits unsigned integet at position [pos]. + /// Throws OutOfRange if [pos+15] >= size(). + + size_t size() const; + /// Returns the number of chars in the object. + + Bytes& operator<<(char v); + Bytes& operator<<(u8 v); + Bytes& operator<<(u16 v); + Bytes& operator<<(u32 v); + Bytes& operator<<(const Bytes& v); + Bytes& operator<<(const char* str); + /// Appends the given data to the vector. Returns *this to allow + /// chaining. + + Bytes& operator>>(u8& v); + Bytes& operator>>(u16& v); + Bytes& operator>>(u32& v); + Bytes& operator>>(char& c); + /// Extracts the given data type from the vector. Returns *this to + /// allow chaining. + + void operator=(const Bytes& oth); + /// Copies the given Bytes object into its own data. + + Bytes sub(size_t beg, size_t len) const; + /// Extracts a sub-bytes, beginning at character [beg], containing + /// [len] chars. If [beg+len] >= [size()], throws OutOfRange. + + void writeToBuffer(void* buff, unsigned maxLen=0) const; + /// Writes the contents of this array in the buffer [buff]. + /// The user must provide a buffer of at least [size()] bytes. + /// If [maxLen] != 0, writes at most [maxLen] bytes to buff. + + void hexdump(Bytes& dest) const; + /// Dumps the packet to [dest] in hexadecimal form. + + private: //meth + template void insertData(T v); + template void extractData(T& v); + + private: + std::vector data; + size_t firstIndex; +}; + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..be9bae1 --- /dev/null +++ b/main.cpp @@ -0,0 +1,13 @@ +/*************************************************************************** + * By Théophile Bastian, 2017 + * M1 Network course project at ENS Cachan, Juliusz Chroboczek. + * License: WTFPL v2 + **************************************************************************/ + +#include "nw_constants.h" +#include "data.h" + +int main(int argc, char** argv) { + //TODO read arguments +} +