Changeset 9b3f53c in nscp for include/nrpe/nrpepacket.hpp
- Timestamp:
- 12/06/09 22:23:10 (4 years ago)
- Branches:
- master, 0.4.0, 0.4.1, 0.4.2
- Children:
- 79e734f
- Parents:
- dcd90b2
- File:
-
- 1 edited
-
include/nrpe/nrpepacket.hpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
include/nrpe/nrpepacket.hpp
r1e0bbec r9b3f53c 22 22 23 23 #include <types.hpp> 24 25 26 class NRPEPacket { 27 public: 28 static const short unknownPacket = 0; 29 static const short queryPacket = 1; 30 static const short responsePacket = 2; 31 static const short version2 = 2; 32 33 class NRPEPacketException { 24 #include <string> 25 #include <unicode_char.hpp> 26 #include <boost/asio/buffer.hpp> 27 28 29 namespace nrpe { 30 // this function swap the bytes of values given it's size as a template 31 // parameter (could sizeof be used?). 32 template <class T, unsigned int size> 33 inline T SwapBytes(T value) { 34 union { 35 T value; 36 char bytes[size]; 37 } in, out; 38 39 in.value = value; 40 41 for (unsigned int i = 0; i < size / 2; ++i) { 42 out.bytes[i] = in.bytes[size - 1 - i]; 43 out.bytes[size - 1 - i] = in.bytes[i]; 44 } 45 46 return out.value; 47 } 48 49 template<EEndian from, EEndian to, class T> 50 inline T EndianSwapBytes(T value) { 51 BOOST_STATIC_ASSERT(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8); 52 BOOST_STATIC_ASSERT(boost::is_arithmetic<T>::value); 53 if (from == to) 54 return value; 55 return SwapBytes<T, sizeof(T)>(value); 56 } 57 template<class T> 58 inline T ntoh(T value) { 59 std::cout << "Swaping (in): " << value << " => " << EndianSwapBytes<EEndian::BIG_ENDIAN_ORDER, EEndian::HOST_ENDIAN_ORDER, T>(value) << std::endl; 60 return EndianSwapBytes<EEndian::BIG_ENDIAN_ORDER, EEndian::HOST_ENDIAN_ORDER, T>(value); 61 } 62 template<class T> 63 inline T hton(T value) { 64 std::cout << "Swaping (out): " << value << " => " << EndianSwapBytes<EEndian::HOST_ENDIAN_ORDER, EEndian::BIG_ENDIAN_ORDER, T>(value) << std::endl; 65 return EndianSwapBytes<EEndian::HOST_ENDIAN_ORDER, EEndian::BIG_ENDIAN_ORDER, T>(value); 66 } 67 68 69 70 class data { 71 public: 72 static const short unknownPacket = 0; 73 static const short queryPacket = 1; 74 static const short responsePacket = 2; 75 static const short version2 = 2; 76 77 typedef struct packet { 78 int16_t packet_version; 79 int16_t packet_type; 80 u_int32_t crc32_value; 81 int16_t result_code; 82 char buffer[]; 83 } packet; 84 85 }; 86 87 class length { 88 typedef unsigned int size_type; 89 static size_type payload_length_; 90 public: 91 static void set_payload_length(size_type length) { 92 payload_length_ = length; 93 } 94 static size_type get_packet_length() { 95 return get_packet_length(payload_length_); 96 } 97 static size_type get_packet_length(size_type payload_length) { 98 std::cout << "get_packet: " << sizeof(nrpe::data::packet) << ":" << payload_length << std::endl; 99 return sizeof(nrpe::data::packet)+payload_length*sizeof(char); 100 } 101 static size_type get_payload_length() { 102 return payload_length_; 103 } 104 static size_type get_payload_length(size_type packet_length) { 105 std::cout << "get_payload: " << sizeof(nrpe::data::packet) << ":" << packet_length << std::endl; 106 return (packet_length-sizeof(nrpe::data::packet))/sizeof(char); 107 } 108 }; 109 110 class nrpe_packet_exception { 34 111 std::wstring error_; 35 112 public: 36 NRPEPacketException(std::wstring error) : error_(error) {}113 nrpe_packet_exception(std::wstring error) : error_(error) {} 37 114 std::wstring getMessage() { 38 115 return error_; … … 40 117 }; 41 118 42 private: 43 typedef struct packet { 44 int16_t packet_version; 45 int16_t packet_type; 46 u_int32_t crc32_value; 47 int16_t result_code; 48 char buffer[]; 49 } packet; 50 std::wstring payload_; 51 short type_; 52 short version_; 53 NSCAPI::nagiosReturn result_; 54 unsigned int crc32_; 55 unsigned int calculatedCRC32_; 56 char *tmpBuffer; 57 unsigned int buffer_length_; 58 public: 59 NRPEPacket(unsigned int buffer_length) : tmpBuffer(NULL), buffer_length_(buffer_length) {}; 60 NRPEPacket(const char *buffer, unsigned int length, unsigned int buffer_length) : tmpBuffer(NULL), buffer_length_(buffer_length) { 61 readFrom(buffer, length); 62 }; 63 NRPEPacket(short type, short version, NSCAPI::nagiosReturn result, std::wstring payLoad, unsigned int buffer_length) 64 : tmpBuffer(NULL) 65 ,type_(type) 66 ,version_(version) 67 ,result_(result) 68 ,payload_(payLoad) 69 ,buffer_length_(buffer_length) 70 { 71 } 72 NRPEPacket() 73 : tmpBuffer(NULL) 74 ,type_(unknownPacket) 75 ,version_(version2) 76 ,result_(0) 77 ,buffer_length_(0) 78 { 79 } 80 NRPEPacket(const NRPEPacket &other) : tmpBuffer(NULL) { 81 payload_ = other.payload_; 82 type_ = other.type_; 83 version_ = other.version_; 84 result_ = other.result_; 85 crc32_ = other.crc32_; 86 calculatedCRC32_ = other.calculatedCRC32_; 87 buffer_length_ = other.buffer_length_; 88 } 89 NRPEPacket& operator=(NRPEPacket const& other) { 90 tmpBuffer=NULL; 91 payload_ = other.payload_; 92 type_ = other.type_; 93 version_ = other.version_; 94 result_ = other.result_; 95 crc32_ = other.crc32_; 96 calculatedCRC32_ = other.calculatedCRC32_; 97 buffer_length_ = other.buffer_length_; 98 return *this; 99 } 100 101 ~NRPEPacket() { 102 delete [] tmpBuffer; 103 } 104 static NRPEPacket make_request(std::wstring payload, unsigned int buffer_length) { 105 return NRPEPacket(queryPacket, version2, -1, payload, buffer_length); 106 } 107 108 const char* getBuffer() { 109 delete [] tmpBuffer; 110 tmpBuffer = new char[getBufferLength()+1]; 111 //TODO readd this ZeroMemory(tmpBuffer, getBufferLength()+1); 112 packet *p = reinterpret_cast<packet*>(tmpBuffer); 113 p->result_code = htons(NSCHelper::nagios2int(result_)); 114 p->packet_type = htons(type_); 115 p->packet_version = htons(version_); 116 if (payload_.length() >= buffer_length_-1) 117 throw NRPEPacketException(_T("To much data cant create return packet (truncate datat)")); 118 //ZeroMemory(p->buffer, buffer_length_-1); 119 strncpy(p->buffer, to_string(payload_).c_str(), payload_.length()); 120 p->buffer[payload_.length()] = 0; 121 p->crc32_value = 0; 122 p->crc32_value = htonl(calculate_crc32(tmpBuffer, getBufferLength())); 123 return tmpBuffer; 124 } 125 126 void readFrom(const char *buffer, unsigned int length) { 127 if (buffer == NULL) 128 throw NRPEPacketException(_T("No buffer.")); 129 if (length != getBufferLength()) 130 throw NRPEPacketException(_T("Invalid length: ") + strEx::itos(length) + _T(" != ") + strEx::itos(getBufferLength())); 131 const packet *p = reinterpret_cast<const packet*>(buffer); 132 type_ = ntohs(p->packet_type); 133 if ((type_ != queryPacket)&&(type_ != responsePacket)) 134 throw NRPEPacketException(_T("Invalid packet type.")); 135 version_ = ntohs(p->packet_version); 136 if (version_ != version2) 137 throw NRPEPacketException(_T("Invalid packet version.")); 138 crc32_ = ntohl(p->crc32_value); 139 // Verify CRC32 140 // @todo Fix this, currently we need a const buffer so we cannot change the CRC to 0. 141 char * tb = new char[getBufferLength()+1]; 142 memcpy(tb, buffer, getBufferLength()); 143 packet *p2 = reinterpret_cast<packet*>(tb); 144 p2->crc32_value = 0; 145 calculatedCRC32_ = calculate_crc32(tb, getBufferLength()); 146 delete [] tb; 147 if (crc32_ != calculatedCRC32_) 148 throw NRPEPacketException(_T("Invalid checksum in NRPE packet!")); 149 // Verify CRC32 end 150 result_ = NSCHelper::int2nagios(ntohs(p->result_code)); 151 payload_ = strEx::string_to_wstring(std::string(p->buffer)); 152 } 153 154 unsigned short getVersion() const { return version_; } 155 unsigned short getType() const { return type_; } 156 unsigned short getResult() const { return result_; } 157 std::wstring getPayload() const { return payload_; } 158 bool verifyCRC() { return calculatedCRC32_ == crc32_; } 159 unsigned int getBufferLength() const { return getBufferLength(buffer_length_); } 160 static unsigned int getBufferLength(unsigned int buffer_length) { return sizeof(packet)+buffer_length*sizeof(char); } 161 unsigned int getInternalBufferLength() const { return buffer_length_; } 162 163 164 std::wstring toString() { 165 std::wstringstream ss; 166 ss << _T("type: ") << type_; 167 ss << _T(", version: ") << version_; 168 ss << _T(", result: ") << result_; 169 ss << _T(", payload: ") << payload_; 170 return ss.str(); 171 } 172 173 }; 174 175 176 177 119 class packet { 120 public: 121 122 123 private: 124 std::wstring payload_; 125 short type_; 126 short version_; 127 int result_; 128 unsigned int crc32_; 129 unsigned int calculatedCRC32_; 130 char *tmpBuffer; 131 unsigned int payload_length_; 132 public: 133 packet(unsigned int payload_length) : tmpBuffer(NULL), payload_length_(payload_length) {}; 134 packet(std::vector<char> buffer, unsigned int payload_length) : tmpBuffer(NULL), payload_length_(payload_length) { 135 char *tmp = new char[buffer.size()+1]; 136 copy( buffer.begin(), buffer.end(), tmp); 137 readFrom(tmp, buffer.size()); 138 delete [] tmp; 139 }; 140 packet(const char *buffer, unsigned int buffer_length, unsigned int payload_length) : tmpBuffer(NULL), payload_length_(payload_length) { 141 readFrom(buffer, buffer_length); 142 }; 143 packet(short type, short version, int result, std::wstring payLoad, unsigned int payload_length) 144 : tmpBuffer(NULL) 145 ,type_(type) 146 ,version_(version) 147 ,result_(result) 148 ,payload_(payLoad) 149 ,payload_length_(payload_length) 150 { 151 } 152 packet() 153 : tmpBuffer(NULL) 154 ,type_(nrpe::data::unknownPacket) 155 ,version_(nrpe::data::version2) 156 ,result_(0) 157 ,payload_length_(nrpe::length::get_payload_length()) 158 { 159 } 160 packet(const packet &other) : tmpBuffer(NULL) { 161 payload_ = other.payload_; 162 type_ = other.type_; 163 version_ = other.version_; 164 result_ = other.result_; 165 crc32_ = other.crc32_; 166 calculatedCRC32_ = other.calculatedCRC32_; 167 payload_length_ = other.payload_length_; 168 } 169 packet& operator=(packet const& other) { 170 tmpBuffer=NULL; 171 payload_ = other.payload_; 172 type_ = other.type_; 173 version_ = other.version_; 174 result_ = other.result_; 175 crc32_ = other.crc32_; 176 calculatedCRC32_ = other.calculatedCRC32_; 177 payload_length_ = other.payload_length_; 178 return *this; 179 } 180 181 ~packet() { 182 delete [] tmpBuffer; 183 } 184 static packet make_request(std::wstring payload, unsigned int buffer_length) { 185 return packet(nrpe::data::queryPacket, nrpe::data::version2, -1, payload, buffer_length); 186 } 187 188 const char* create_buffer() { 189 delete [] tmpBuffer; 190 unsigned int packet_length = nrpe::length::get_packet_length(payload_length_); 191 tmpBuffer = new char[packet_length+1]; 192 //TODO readd this ZeroMemory(tmpBuffer, getBufferLength()+1); 193 nrpe::data::packet *p = reinterpret_cast<nrpe::data::packet*>(tmpBuffer); 194 p->result_code = nrpe::hton<int16_t>(result_); 195 p->packet_type = nrpe::hton<int16_t>(type_); 196 p->packet_version = nrpe::hton<int16_t>(version_); 197 if (payload_.length() >= payload_length_-1) 198 throw nrpe::nrpe_packet_exception(_T("To much data cant create return packet (truncate datat)")); 199 //ZeroMemory(p->buffer, payload_length_-1); 200 strncpy(p->buffer, ::to_string(payload_).c_str(), payload_.length()); 201 p->buffer[payload_.length()] = 0; 202 p->crc32_value = 0; 203 p->crc32_value = nrpe::hton<u_int32_t>(calculate_crc32(tmpBuffer, packet_length)); 204 std::wcout << _T("About to send: ") << to_string() << std::endl; 205 std::wcout << _T("About to send: ") 206 << _T("") << strEx::ihextos(tmpBuffer[0]) 207 << _T(", ") << strEx::ihextos(tmpBuffer[1]) 208 << _T(", ") << strEx::ihextos(tmpBuffer[2]) 209 << _T(", ") << strEx::ihextos(tmpBuffer[3]) 210 << std::endl; 211 return tmpBuffer; 212 } 213 214 void readFrom(const char *buffer, unsigned int length) { 215 std::wcout << _T("Just read: ") 216 << _T("") << strEx::ihextos(buffer[0]) 217 << _T(", ") << strEx::ihextos(buffer[1]) 218 << _T(", ") << strEx::ihextos(buffer[2]) 219 << _T(", ") << strEx::ihextos(buffer[3]) 220 << std::endl; 221 if (buffer == NULL) 222 throw nrpe::nrpe_packet_exception(_T("No buffer.")); 223 if (length != get_packet_length()) 224 throw nrpe::nrpe_packet_exception(_T("Invalid packet length: ") + strEx::itos(length) + _T(" != ") + strEx::itos(get_packet_length()) + _T(" configured payload is: ") + to_wstring(get_payload_length())); 225 const nrpe::data::packet *p = reinterpret_cast<const nrpe::data::packet*>(buffer); 226 type_ = nrpe::ntoh<int16_t>(p->packet_type); 227 if ((type_ != nrpe::data::queryPacket)&&(type_ != nrpe::data::responsePacket)) 228 throw nrpe::nrpe_packet_exception(_T("Invalid packet type: ") + strEx::itos(type_)); 229 version_ = nrpe::ntoh<int16_t>(p->packet_version); 230 if (version_ != nrpe::data::version2) 231 throw nrpe::nrpe_packet_exception(_T("Invalid packet version.") + strEx::itos(version_)); 232 crc32_ = nrpe::ntoh<u_int32_t>(p->crc32_value); 233 // Verify CRC32 234 // @todo Fix this, currently we need a const buffer so we cannot change the CRC to 0. 235 char * tb = new char[length+1]; 236 memcpy(tb, buffer, length); 237 nrpe::data::packet *p2 = reinterpret_cast<nrpe::data::packet*>(tb); 238 p2->crc32_value = 0; 239 calculatedCRC32_ = calculate_crc32(tb, get_packet_length()); 240 delete [] tb; 241 std::wcout << _T("Just read: ") << to_string() << std::endl; 242 if (crc32_ != calculatedCRC32_) 243 throw nrpe::nrpe_packet_exception(_T("Invalid checksum in NRPE packet: ") + strEx::ihextos(crc32_) 244 + _T("!=") + strEx::ihextos(calculatedCRC32_)); 245 // Verify CRC32 end 246 result_ = nrpe::ntoh<u_int32_t>(p->result_code); 247 payload_ = strEx::string_to_wstring(std::string(p->buffer)); 248 } 249 250 unsigned short getVersion() const { return version_; } 251 unsigned short getType() const { return type_; } 252 unsigned short getResult() const { return result_; } 253 std::wstring getPayload() const { return payload_; } 254 bool verifyCRC() { return calculatedCRC32_ == crc32_; } 255 unsigned int get_packet_length() const { return nrpe::length::get_packet_length(payload_length_); } 256 unsigned int get_payload_length() const { return payload_length_; } 257 258 boost::asio::const_buffer to_buffers() { 259 return boost::asio::buffer(create_buffer(), get_packet_length()); 260 } 261 std::wstring to_string() { 262 std::wstringstream ss; 263 ss << _T("type: ") << type_; 264 ss << _T(", version: ") << version_; 265 ss << _T(", result: ") << result_; 266 ss << _T(", payload: ") << payload_; 267 return ss.str(); 268 } 269 static nrpe::packet create_response(int ret, std::wstring string, int buffer_length) { 270 return packet(nrpe::data::responsePacket, nrpe::data::version2, ret, string, buffer_length); 271 } 272 }; 273 } 274
Note: See TracChangeset
for help on using the changeset viewer.








